Question

I bump into this from time to time during class design... when I have several properties of the same type in the object. Take few examples:

User has several addresses. We can do

IDictionary<string, Address> Addresses; // Addresses["BusinessAddress"];

or

Address BusinessAddress; 
Address ShippingAddress;

Product has related products, by different cagetories. We can do

IDictionary<string, IList<Product>> Related; // Related["Available"];

or

IList<Product> Available;
IList<Product> Required;

User has several roles assigned. We can do

IList<Role> Roles;

or

bool IsAdmin;
bool IsSales;

So, what's better? IDictionary is more flexible as we can easily add new address categories into the database without even touching the code. But the drawback is that we use strings to access; this is always error-prone. We can solve this with either unit tests or constants like

public class ProductCategories { public static string Available = "Available"; }

But it is still much worse to read "product.Available" than "product.Related[ProductCategories.Available]".

There are other considerations, like, what's easier/better to map with ORM (e.g. NHibernate).

But the question is, are there any known preferences? Design articles and/or books on this subject? Real world practices that people here experienced?

For example, we can combine both worlds... have IList and bool IsAdmin doing "return Roles.Contain(Role("Admin"));". But this looks ugly to me.

Or, in case of IDictionary we can't have more than 1 address per type; and if we do

IDictionary<string, IList<Address>>

this is going crazy for simple addresses where we don't need multiples. But if we use BillingAddress, ShippingAddress, and IList for MultipleAddress, we have a much more fine-grained control over our addresses... with Intellisense and so on.

Was it helpful?

Solution

Since you mention Domain-Driven Design (DDD), the book of the same title contains guidelines for Intention-Revealing Interfaces. Having a dictonary of Domain objects is by no way intention-revealing, so for that reason alone, I would strongly recommend against Dictionaries.

Dictionaries should mostly be used to expose an API where callers will have the ability to both add and retrieve values, or for very general-purpose infrastructure APIs, where you need to be able to deal with a very flexible set of situations.

This is not the case for DDD. Imagine that you didn't write the class yourself, and then encounted the Dictionary-based Addresses property from your example. How would you know which types of addresses it contains? You would have to look at the implementation code or read the documentation.

If, on the other hand, you have both a BusinessAddress and a ShippingAddress property, it is immediately obvious to the consumer of the API what's available.

I think the flexibility you think about is a false sense of flexibility, since client code still needs to know which dictionary entries are available before they can consume them. It is just as easy to add a new property to a class as it is to add an entry to a Dictionary.

If you really need a Dictionary (or better, a list) because sometimes you need to iterate over all Addresses (or whatever), you can do this by exposing a read-only property that provides an enumerator over both - something like this:

public Address BusinessAddress { get; set; }
public Address ShippingAddress { get; set; }

public IEnumerable<Address> Addresses
{
    yield return this.BusinessAddress;
    yield return this.ShippingAddress;
}

OTHER TIPS

It depends. If your application needs to allow users to add addresses, then by all means have a dictionary of Addresses.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top