views:

106

answers:

4

Consider a production planning application with many products. Each product has a list of InventoryControl objects keyed on InventoryControlType. Depending on the algorithm we run for production planning, we need to access to different types of InventoryControl objects for a given product. This works OK. However, today I needed to introduce a field in InventoryControl that holds the InventoryControlType since deep in our algorithms we needed to know the InventoryControlType.

However, I felt felt like I was doing something wrong since it looks like I am repeating data.

Does this design look OK to you? Any ideas for improvement?

class Product{
    Dictionary<InventoryControlType, InventoryControl> InventoryControls;
    GetInventoryControl(InventoryControlType type){
        return InventoryControls[type];
    }
}

class InventoryControl{
    InventoryControlType controlType;
    float limit;
    float cost; 
    ...
    CalculateCost(){...}
    GetConstraint(){...}
}
+5  A: 

I think you're fine. It's perfectly normal (at least in my experience) to use a unique property of an object as a key--be it in a Dictionary, a DataTable, or what have you.

For example in my own work our major project features a class called Product with a property called Symbol, and the application maintains a Dictionary called Products with each Product object's Symbol property serving as its key.

Think of it this way: if you have a database with two tables, and one table references rows in the other by key, it may feel like you are "duplicating" data in the sense that you have the same number (the key) in two places. But that is not duplication; it's a reference. The same applies in your scenario.

Dan Tao
+1  A: 

I don't see anything inherently wrong with it. It is duplicating a piece of information, but the situation does call for it. You could use a normal collection instead of a Dictionary--but because your main goal is to find a piece of information based on its InventoryControlType, Dictionary, with this implementation, seems most correct.

Brisbe42
+1  A: 

I think it's absolutely fine for a Dictionary<TKey, TValue> use case.

Many times Dictionary objects will always have some sort of redundant information from the value object, the most common of which will be an ID, e.g. Dictionary<int, SomeObject> where int will be a value taken from SomeObject.Id -- it makes sense in that respect, and it's perfectly identical to your use case.

Jon Limjap
+1  A: 

It really depends on how big the dictionary is supposed to get, because for very large amounts of data, I think the lookup on the dictionary using the key would probably be faster. But if you don't have very large amounts of data, you could use Linq and a Generic List. For example:

class Product{
List<InventoryControl> InventoryControls;
GetInventoryControl(InventoryControlType type){
    return InventoryControls.First(x => x.ControlType == type);
}

I would recommend running some unit test benchmarks to see whether the Dictionary is required.

alord1689