Alex Jeffery
Alex Jeffery

Reputation: 187

Domain Model Design

How would you create a domain model for this simple example? A recipe can have many ingredients and an ingredient can be used in many recipes. How much of each ingredient used in each recipe is also stored. I have designed the following three database tables to store this data and the relationships.

I am now trying to create a domain model to represent this. I have a basic example with two classes. I then ran into trouble with this model when I thought about creating a new ingredient. There would need to be a class with out the quantity property. How should this be modeled?

Database Tables

alt text http://img190.imageshack.us/img190/340/databasex.png

Domain Model

alt text http://img24.imageshack.us/img24/8859/classesy.png

Upvotes: 2

Views: 2237

Answers (4)

Rob
Rob

Reputation: 11733

I think you guys are all lost. The original poster had the right impulse, but was taking the wrong route. Actually, the mapping table he shows, using the old Riehl heuristic (combining the names of the l and r relations) seems to be addressing the fact that it's a many-to-many mapping. But what is really happening is that you need a role class here (Coad's Domain Modeling approach used these a lot). Here's the thing though: that's what Ingredient is already! The missing abstraction here opens a can of worms though: it's the thing that's being added. One could argue that that would be a base class, e.g. Food (since we literally, by definition cannot add inedible things to a recipe), but then you have the burden of accounting for all foods, or you can just name them.

So the correct model I think is Recipe contains Ingredients which have some amount of a specific Food.

Upvotes: 0

JuanZe
JuanZe

Reputation: 8157

If you are trying to do domain-driven design don't start with tables. Elaborate first a conceptual model that reflects your underlying domain. I agree with ndp: RecipeIngredient is a bit of an awkward name/concept, from a DDD perspective.

I think the model needs the following concepts: Recipe, Ingredient, Measure and RecipePreparation.

A Recipe is an aggregation of Ingredients. Each Ingredient belonging to a Recipe need a Measure associated to it, as a specification for the preparation. Also you need to model the RecipePreparation to associate the actual quantity of each ingredient used during a specific preparation of the recipe.

A Measure consists of unit and amount (e.g. 2 cups, 0.5 oz, 250 gr, 2 tbsp...).

I see here two different things that could be mixed during analysis and should be kept split: Recipe/Ingredient/Measure as a specification in order to cook something (one instance for each recipe) and RecipePreparation/Ingredient/Measure as a concrete preparation of one recipe, done by a specific person on a specific moment, and may be using different measures (doubled all the ingredients because the recipe specification is for two plates and you have four guests... something like that).

You can go deeper and start modeling things like some ingredients having a set of exchangeable ingredients (e.g. if you don't have goat's cheese use mozzarella), a cookbook that collect a set of recipes of the same category, a cooking time for the recipe, etc.

Upvotes: 3

ndp
ndp

Reputation: 21996

Since you have data in your join table (quantity), the answer is that you need a class to represent it. (There are other alternatives, but not worth considering.)

As your model grows, you will undoubtedly need to add more data here. For example, how do you set the order of the ingredients in the recipe?

RecipeIngredient is a bit of an awkward name (and concept), from a domain driven design perspective. You may be able to come up with different names that feels better. But in general, this is a necessary implementation detail. Sorry, I don't have the Evan's DDD book handy to provide a reference.

Upvotes: 0

Ash
Ash

Reputation: 62096

In your domain model create a RecipeIngredient class containing a reference to a specific Ingredient and a Quantity.

Then change the Recipe.Ingredients list to contain RecipeIngredient objects. Finally remove Quantity from the Ingredient class.

Just a tip: most purist domain modellers would say you should create your domain model first and not concern yourself with the database until much later.

Upvotes: 2

Related Questions