views:

39

answers:

2

having a tough time figuring out how to model the expected product behavior.

Basically, the customer's inventory is managed along products and skus.

A product has many skus, but a single sku accounts for several product attributes.

Let me give an example.

Let's say i'm selling you a shirt. "Shirt" is the product with some product ID. If it comes in small, medium, large, then each of those sizes would be associated with a sku #.

easy enough so far, but if the shirt also comes in multiple colors, let's say red, yellow, and green, then there will be nine skus (red/small, red/medium, red/large, yellow/small, and so on).

Add to that the challenge that the types of attributes can be different for different products. A shirt might have sizes and colors, a handbag might have different handle styles or patterns, and I won't know ahead of time, these are things that the customer needs to be able to input in an adhoc fashion.

Any ideas on how to approach this from a DDD perspective? I"ve been baking my noodle on it for a few days now.

Thanks.

A: 

First of all you have to regard each sku as a single product attribute and not combine them. If a product can have a color and a size, these are two distinct attributes, not one (as in red/small, red/medium, etc). Suppose a product has five attributes, each with 4 possible values. You would then have 4^5=1024 skus. This quickly becomes a maintenance nightmare.

So, the first two objects in your domain model should be ProductDefinition and Attribute. The reason I choose ProductDefinition as a name and not Product is that this is just a label for some product type, a shirt for example. It is not yet a small yellow shirt.

Attributes can have possible values, so this makes for a third domain object: AttributeValue. The relation between Attribute and AttributeValue is 1:n. An attribute has multiple values, a value only belongs to one attribute.

Note that AttributeValue contains all possible values for an attribute, not the actual value for a single product. This actual value becomes a relation between ProductDefinition, Attribute and AttributeValue: ProductAttributeValue. Up for the shirt example in a database model:

ProductDefinition   Attribute       AttributeValue
1 | Shirt           1 | Color       1 | 1 | Red
                    2 | Size        2 | 1 | Yellow
                                    3 | 1 | Green
                                    4 | 2 | Small
                                    5 | 2 | Medium
                                    6 | 2 | Large

We have now modeled one product definition, two attributes and three attribute values per attribute. Suppose now we want to model three shirts: a small red one, a small green one and a large yellow one. This results in the following ProductAttributeValue content (ProductId, ProductDefinitionId, AttributeId, AttributeValueId):

ProductAttributeValue
1 | 1 | 1 | 1
1 | 1 | 2 | 4
2 | 1 | 1 | 3
2 | 1 | 2 | 4
3 | 1 | 1 | 2
3 | 1 | 2 | 2
Ronald Wildenberg
I appreciate the answer, Ronald, but the business problem I'm trying to solve *is* that each combination of attributes maps to a unique sku. That's the customer's requirement, not mine, and I can't change it. Also, your answer looks very database-oriented, where I was trying to work through it as domain objects (though that's a minor point; the algorithm matters more than style).
Dr. Evil
I understand, but I would not let the customer definition of an sku drive your domain (database) model. It's true that my model is very database oriented, but in the end that is where you have to store your data. The database model should somehow be a representation of the domain you're modeling. An sku is something that should be defined a level higher than the database model, combining records from my ProductAttributeValue table. That is just a matter of representation. If you want to show skus to the customer, this is possible using the model I described.
Ronald Wildenberg
But I don't see where, in your description, skus fit in at all.
Dr. Evil
They can be derived from ProductAttributeValue. For example, the first two rows represent a shirt with sku small/red.
Ronald Wildenberg
No, they're user provided, not derived.
Dr. Evil
I understand, but that is something your user interface should make possible. You should give your end user an interface that makes it possible to provide skus. But that does not solve your problem of how to represent them in the backend of your application. I do not suppose the user can provide skus in some freetext format?
Ronald Wildenberg
A: 

We did a system like this..

ProductDefinition
  has Type (Shirt, Handbag)
  has many ProductFieldDefinition

ProductFieldDefinition
  has Type (Color, size, pattern)

Product
  has ProductDefinition
  has SKU
  has many ProductField
      has ProductFieldDefinition
      has Value

The one thing I would change in our system is I would use a Document Database to store everything but in our case the graph actually went much deeper with each level having it's own fields.

ShaneC