The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

What is the proper Domain Model for this relationship?

This is a simplified example of my problem.
A Customer can have multiple Products and a Product can be assigned to zero to more Customers
But, there are some items (such as BasePrice and DefaultPrefix) that are defined only for an instance of a customer-product relationship.
In the database this can be modeled as
Table Customer with Columns CustomerId, Name, etc.
Table Product with Columns ProductId, Name, etc.
Table CustomerProduct with Columns CustomerId, ProductId, BasePrice, DefaultPrefix, etc.

How would you model this in a domain object model?
All I could think of is
Customer
..CustomerId
..Name
..AssignedProduct[] Products
Product
..ProductId
..Name
..Customer[] Customers
AssignedProduct : Product
..Customer Customer
..BasePrice
..DefaultPrefix

But that doesn't strike me as too slick (an Assigned Product has a Customer and a Customers[]???) and as this simplified example gets closer to what I actually have to model, this design starts to have problems among which is that NHibernate can't model some of this stuff
Send private email
Friday, August 08, 2008
 
 
Let me try ...

1. Instead of making Assigned product a specialization of
  Product, I would prefer Composition.
  AssignedProduct
  ...Customer Customer
  ...Product product
  ...BasePrice
  ...DefaultPrefix

2. I would model the Customer as follows.
  Customer
  ...CustomerId
  ...Name
  ...AssignedProduct[] AssignedProducts
  Optionally Product[] Products (most probably not required)

AssignedProduct is a link between Customer and Product. AssignedProduct does not have a "is a" relationship with Product. In other words AssignedProduct is not a kind of product. Therefore, I would not couple these classes through inheritance.

Friday, August 08, 2008
 
 
Hmm, I guess that makes sense.  I need to find a better names then.  Is there a typical naming scheme that people like for these association objects?
George Mauer Send private email
Friday, August 08, 2008
 
 
What does it mean for a customer to "have" a product.  I'm accustomed to thinking of customers as buying products, but not "having" them. 

I don't intend to start a philosophical discussion on the meaning of data, here.  But until I know what you mean,  I can't say whether or not I agree with the way you've modeled the data.
Walter Mitty Send private email
Friday, August 08, 2008
 
 
Well maybe it will help if I flesh out the model a bit.
At its base, the system is for a company with multiple sites (as in locations) that rents out liquid storage containers.
So with this fleshed out model we have the following:
Location with 0:n Customers.
A Customer can exist independantly of a Location, but once he is at a Location he can own 0:n Products.
Like a Customer, a Product can exist independently.
Similarly, each Customer at a given Location can put a given Product in 0:n Containers.
Again, a Container can exist independently but can only be filled by a Product that is assigned to a Customer which must in turn be assigned to a Container.

Given the above suggestion I would have to have the following set of objects:
Location, Customer, Product, Container,
LocationCustomerRelation, LocationCustomerProductRelation, LocationCustomerProductContainerRelation

I don't know how I feel about all these relation objects.  Im still looking for suggestions
George Mauer Send private email
Saturday, August 09, 2008
 
 
I think you're over-complicating the design with all those relationship objects.

You should be able to get away with these:
* Customer
* Product
* Location
* Container
* AssignedProduct (I'd be tempted to rename this - what do your users call it?)

Here are the domain model relationships:
* Location  1<-->m  Customer
* Customer  1<-->m  AssignedProduct
* Container 1<-->m  AssignedProduct
* AssignedProduct  1<-->1  Product
* AssignedProduct  1<-->1  Customer
* AssignedProduct  1<-->1  Container

Are you trying to practice Domain Driven Design? It seems that you're designing with the database first, and considering the domain model afterwards.  The relationships you suggested are akin to database constraints, not domain constraints.

I've knocked together a prototype that may help you explore and tweak your domain model (and it’s NHibernate friendly). You can download it here: http://www.evolving-software.co.uk/downloads/Domain-Model-Example.zip  . Just run the EXE in the Debug folder.

Feel free to tweak the source code and re-run the prototype – the UI will show your changes instantly.  The example is quite straightforward, but feel free to ask further questions.

Cheers.
Vijay Patel
Monday, August 11, 2008
 
 
Vijay,
I will look at your prototype, thank you.  I am designing an object library for a legacy database so yes, the database comes first.  However, the database was created by domain experts and not developers so those relationships I listed are about right for the domain.

Regarding you're proposed model, I'm not sure I understand
* Customer  1<-->m  AssignedProduct
* Container 1<-->m  AssignedProduct
* AssignedProduct  1<-->1  Customer
* AssignedProduct  1<-->1  Container
Am I missing something?  How is that possible?  Also, what I mentioned before about relationships entailing additional data applies to the newly mentioned objects too.  A customer-to-location-association for example would imply the presnce of a local office so it must store the address, likewise container-to-product-association would have to come with a base price that we would use to charge the customer for storing that type of product in that type of container.

As for naming, that is why I originially had AssignedProduct set up as inheriting from Product.  A manager of a location can talk about all the products present at the site, or he might talk about only the products that have been assigned to customers - hence why I made one a specialization of the other.  The question of how to store the aditional data about the relation is exactly my problem.
George Mauer Send private email
Monday, August 11, 2008
 
 
George,

Working from the database back towards the Domain Model is always tricky – your domain model may end up carrying database style semantics.

“…A customer-to-location-association for example would imply the presnce of a local office so it must store the address…”
Agreed. You need a first class object to support this.

“…container-to-product-association would have to come with a base price that we would use to charge the customer for storing that type of product in that type of container…”
This is what the “AssignedProduct” object is meant to hold.  Maybe calling it “StoredProduct” would make more sense?

“…A manager of a location can talk about all the products present at the site, or he might talk about only the products that have been assigned to customers…”
The “AssignedProduct” is the key to this.  If you want all Products for a given Location, you would iterate* through all AssignedProducts for all Containers at that location.  If you want all Products for a particular Customer, you would find all AssignedProducts that match the Customer.

(* or you could use a SQL statement to join the relevant tables)

Cheers.
Vijay Patel
Monday, August 11, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz