views:

409

answers:

4

My colleague and I have been having a discussion about what Collections should be called.

For example:

Class Product - Collection - Class Products

or

Class Product - Collection - Class ProductCollection

I've had a look around to see if I can see any guidelines or reasons for using one or the other but nothing seems to spring out. The framework seems to use both variants for example. The argument I can see is that a class that has a collection of products variable should be called Products but it should be of type ProductCollection.

Which is correct if any?

In the same vane is there a standard for the naming of return variable for a function. e.g. retVal?

We mainly code in C#, although I'm not sure that affects my question.

+30  A: 

I would say that with generics there should rarely ever be a reason to create a custom collection type. But if you must I would say that ProductCollection would best fit the naming conventions of the framework.

Still, consider using a List<Product> or Collection<Product> or better yet IList<Product> or ICollection<Product>.

Edit: This is in response to MrEdmundo's comments below.

In your case you have two choices. The most obvious choice would be to use inheritance like this:

class Ball { }

class BallCollection : List<Ball>
{
    public String Color { get; set; }
    public String Material { get; set; }
}

I say obvious because it seems like the best idea at first glance but after a bit of thought it becomes clear that this is not the best choice. What if you or Microsoft creates a new SuperAwesomeList<T> and you want to use that to improve the performance of your BallCollection class? It would be difficult because you are tied to the List<T> class through inheritance and changing the base class would potentially break any code that uses BallCollection as a List<T>.

So what is the better solution? I would recommend that in this case you would be better off to favor composition over inheritance. So what would a composition-based solution look like?

class Ball { }

class BallCollection
{
    public String Color { get; set; }
    public String Material { get; set; }
    public IList<Ball> Balls { get; set; }
}

Notice that I have declared the Balls property to be of type IList<T>. This means that you are free to implement the property using whatever type you wish as long as that type implements IList<T>. This means that you can freely use a SuperAwesomeList<T> at any point which makes this type significantly more scalable and much less painful to maintain.

Andrew Hare
+1: Totally agree with all of the above. If you have to do it, name it XxxCollection. But don't do it if you can avoid it.
David M
+1 for using built-in collection types.
Darin Dimitrov
+1 for generic collection, and don't forget the basic IEnumerable<Product>
Joel Coehoorn
Thanks - In this case I am inheriting from List<T> to allow for some custom properties, hence the requirement to name the collection.
MrEdmundo
@MrEdmundo: Aha, I see. In that case I would use ProductCollection. One word of caution: would your problem be better solved by means of composition? In other words it may be easier to manage/scale your type if it *contained* a `List<Product>` as opposed to inheriting from it.
Andrew Hare
So your saying I would be better off having an Object with the List<Product> as a property as well as the custom properties rather than have class that inherits from list with the custom properties? I've not come across why that would be more scalable could you point me in the right direction?
MrEdmundo
Sure thing! What are some of the properties that you are adding? If you can give me an idea of what you are trying to do I can edit my answer to include an example.
Andrew Hare
OK. This isn't what I'm using but seems to make sense. Imagine I have a bag, and that bag contains balls. The bag has properties Color and Material (string). I think I can see what you're going to say. Is it a decision as to whether the bag "is" a collection of balls, or whether the balls in the bag are merely an attribute of a bag?
MrEdmundo
The color and material of the ball are attributes of the balls themselves. As such, you collection does not need to know about them. I think in this case you don't need to create a new type as a `List<Ball>` ought to work just fine.
Andrew Hare
Sorry I think I must have explained it badly. The Color and the Material refer to that of the bag. e.g. The Blue Bag made of Nylon contains Balls.
MrEdmundo
I am also interested in the answer to MrEdmundo's latest comment.
Mike C.
@MrEdmundo: In that bag with balls case, I think I would create a class called Bag with the Color and Material properties. In addition I would probably give it a property called Contents or something of type IEnumerable<Ball> or IList<Ball> or IList<Toy> or something like that.
Svish
When I think more about it, I would maybe make Bag implement IEnumerable<Toy> and have the Contents property be IList<Toy> (or swap Toy with Ball). I'm not an expert though :p
Svish
Thank you for your time. I appreciate the thorough answer. Ed
MrEdmundo
+11  A: 

Products is certainly not correct IMHO. A non-static class name should represent a noun (not plural), because you should be able to say "x is a [classname]".

Obviously, Products doesn't fit in that scheme. ProductCollection does:

Illustration:

var products = new Products(); // products is a Products

var products = new ProductCollection(); // products is a ProductCollection

Which one "sounds right" ?

Another thing about naming collection classes: I usually try to name collection classes in such way that it is clear what kind of collection it is.

For example:

  • class ProductCollection: can only be enumerated and the Count retrieved (i.e. only implements ICollection interface(s))
  • class ProductList: a list that can be manipulated using Add(), Insert(), etc. (i.e. implements IList interface(s))
  • class ProductDictionary: a dictionary of products accessible by some key (i.e. implements IDictionary interface(s))

The last one can be ambiguous if there could be a doubt what the key of the dictionary is, so it's better to specify what the key type is (like ProductDictionaryByString). But to be honest, I rarely name it this way because most of the time the key will be a string anyway.

Philippe Leybaert
Wouldn't it be better to use `products` instead of `list` as variable name in those examples?
Svish
Of course, good point. In real code it would be much better, but this is simply an illustration of why classes should be named in a certain way.
Philippe Leybaert
+3  A: 

The .NET Framework frequently uses a "Collection" postfix for its collection types. StringCollection, ObservableCollection, KeyedCollection, etc. So go with ProductCollection.

Randolpho
+3  A: 

Noticed nobody answered you on the retVal stuff (Or I could just be getting blind). Although I'm not an expert; on the matter of the retVal issue I'm not 100% sure what you mean by "naming of return variable", but if you mean stuff like this:

public void GetSomething(out object retVal) 
{
    retVal = ThingFactory.CreateSomething();
}

I would say, no matter what the convention is, don't do it. It's very annoying. Just return the value instead. If you need to return more than one thing, then I would think the method either does more than one thing (which a method shouldn't) or those things should be wrapped up in some sort of logical class that could be returned instead.

If instead by "naming of return variable" you mean stuff like this:

var retVal = ThingFactory.CreateSomething();

Then I would say name the variable according to what it is. What it is going to be used for. If its a list of cars, call it listOfCars, if it's a piece of bread to be eaten later, call it pieceOfBread or pieceOfBreadToBeEatenLater.

Hope that helped and that it wasn't too far off into a field somewhere :p

Svish