DDD: Modeling M:N relation between two roots where the relation itself carries semantic meaning - oop

Update Edited to reflect clarifications requested by Chris Holmes below. Originally I was referring to a Terminal as a Site but changed it to better reflect my actual domain.
At heart, I think this is a question about modeling a many to many relationship between two root entities where the relationship itself carries some semantic meaning.
In my domain
You can think of a Terminal as a branch location of our company
A Terminal can have a relationship with any number of customers
A customer can have a relationship with any number of terminals (standard many to many)
A customer\terminal relationship means that a customer can potentially store products at the Terminal
This relationship can be enabled\disabled. To be disabled merely means you are temporarily not allowed to store product, so a disabled relationship is different from no relationship at all.
A customer can have many Offices
A Terminal that has a relationship with a customer (enabled or not) must have a default office for that customer that they communicate with
There are some default settings that are applied to all transactions between a Customer and a Terminal, these are set up on a Terminal-Customer Relationship level
I think my objects here are pretty clear, Terminal, Customer, Office, and TerminalCustomerRelationship (since there is information being stored specifically about the relationship such as whether it is enabled, default office, ad default settings). Through multiple refactorings I have determined that both Terminal and Customer should probably be aggregate roots. This leaves me with the question of how to design my TerminalCustomerRelationship object to relate the two.
I suppose I could make the traversal from Terminal to TerminalCustomerRelationship unidirectional toward the relationship but I don't know how to break the relation from the relationship to the customer, especially since it needs to contain a reference to an Office which has a relationship to a Customer.
I'm new to this stuff and while most of DDD makes perfect sense I'm getting confused and need a fresh outlook. Can someone give me their opinion on how to deal with this situation?
Please note that I say Relationship not relation. In my current view it deserves to be an object in the same way that a Marriage would be an object in an application for a wedding chapel. Its most visible purpose is that it relates two objects, but it has other properties that rightfully belong to it as well.

By your description, you definitely need a "TerminalCustomerRelationship" entity to track the associated information. I would also convert the 'IsEnabled' flag into a first class 'Event' entity with a timestamp - this gives you the ability to save a history of the state changes (a more realistic view of what's happening in the domain.)
Here's a sample application (in VS2008) that refects your problem. You can tweak/test the code until the relationships make sense. Run "bin/debug/TerminalSampleApp.exe" and right-click "Terminal->Create Example" to get started.
Let me know if you find it useful.

Names can often clarify an object's responsibilities and bring a domain model into focus.
I am unclear what a Site is and that makes the entire model confusing, which makes it difficult for me to offer better advice. If a Site were a Vendor, for instance, then it would be easy to rename SiteCustomerRelationship as a Contract. In that context it makes perfect sense for Contract to be its own entity, and have the the model look like Vendor-Contract-Customer-Office.
There are other ways to look at this as well. Udi has a decent post on this sort of many-to-many relationship here.

You should not have a object Like SiteCustomerRelationship, its DB specific.
If its truly DDD you should have a Relation like:
Aggregate<Site> Customer.Site
IEnumerable<Aggregate<Office>> Customer.Offices
and perhaps
Aggregate<Office> Customer.DefaultOffice

Related

Is this Library Management System ER diagram correct?

Quick question about an ER/EER Diagram.
I have made this Entity Relationship Diagram, but I have been told, that there is something wrong with it by a friend. Is there something wrong with it?
The ER diagram is a design of a Library Management System, where a member can borrow 5 books at a time. The rest of the functionality of the system is how a normal library functions.
Library Management System EER
i don't understand the utility of the relationship between the librarian and the card and i don't understand why the books are splitted in two entities.
I would do 3 entities:
-member
-card
-book
every member has one card, every card is of one member;
every member can take many books, every book can be taken by many members,
the relation between member and book create another table in the logic schema: loans. before inserting a new loan you can check if the member has alredy 5 active loans (by checking the attribute active in the loans table).
Your given context is incomplete for me. I do not see the whole description of your problem/situation, so I will answer based on assumptions, and the experience I had during my life. So let's see...
The tino user questioned the existence of two entities, title and volume, which is something important. Let me explain this for a moment, which will eliminate this as an error. Previously (a time ago) we had video rental stores (I don't know if this the right name where you live, english is not my native language). Remember? We used to go there to rent VHS tapes to watch at home.
What we rented were not films, but more copies/midia of them. A film will always have the same actor, director, title, etc., but a copy could have different attributes/properties, like the year that the media was manufactured, the available languages, the expiration year, among other things. So we had distinctly two different things.
But despite this, we have to consider whether there is a need to create two entities for persistence. We have to remember if we need to persist this information. If a copy/midia has no attributes, then it's entity should not exist, and what a user would rent really would be the movies titles.
In your case, the relationship between volume and title, I belive, is really expressing this discrepancy.
Let's talk about the relationship between librarian and title. What a librarian manages? Does It manages the titles that never change and are abstract things, or the physical objects present in the library? :)
Finally, let's talk about the borrows relationship. When we break down 1-N (or N-1) relationships, we always pass the primary key from the 1 side to the N side, solving the relationship to the formation of the Physical Model in a Entity-Relationship Diagram.
Despite this relationship here is a 0-5, to decompose it, we will not have exactly a 0-5 relationship. We would have in anyway to pass the primary key from the two sides to the table formed by this relationship. Therefore, here we have initially a N-N relationship between member and volume.
N-N relationships allow optional relations between entities. This means we can have the zero side cardinality here. To limit the number of books that can be rented, you need to implement a restriction/constraint with SQL, or with any procedural language in your database. In this case, you can implement a before insert trigger. This trigger has a duty to verify this restriction to allow or denny the completion of the operation as a whole.
Let it be clear that I'm not saying you should remove this notation. Your Conceptual Model should express it. But when you are decomposing, you have to remember that. I think you should just correct it.
Remember one important rule: Relations that have attributes/properties (the attributes/properties) can only exist in N-N relationships. If you have to put attributes/properties in a 1-N (or a N-1) relation, they (the attributes/properties) will always be on the N side. In summary, there are no N-1 (or 1-N) relationships with attributes in the relation. Only N-N relations can have attributes/properties. So be careful with this.
Any questions or clarification, please comment and I will answer.
I see no reason to distinguish member and card. Volume and Librarian don't have primary keys. Are they supposed to be weak entities? That doesn't make sense for Librarian and Volume needs an identifier to distinguish different copies.

Supertype/subtype of weak/associate entity in ERD

I have some questions need to be answered. The requirement is to build a database for university entrance system:
"Applicant may apply to 5 university, each university may or may not interview the applicant, then, make an offer to the applicant. The offer may or may not be conditional (conditional/uncondtional), if the offer is conditional, the conditions are stored. The applicant need to choose which conditional offers he/she wishes to accept, up to maximum of 3. If any of the conditions is met when end of the year, the offer becomes unconditional, then, applicant may accept that one."
There are some notable points:
The course work requires using some enhanced ER features such as supertype/subtype.
Regardless the offer is conditional or unconditional, the applicant can accept the offer. Am I right?
In my ERDs, the APPLICATION entity is a weak entity, using a surrogate key, and UNIQUE_CONSTRAINT on University_ID and Applicant_ID.
In my ERD (on working), there are 2 versions. The ERD_1 is a suggestion of my friends. But I think, my work on ERD_2 is more accurate. I have questions:
Am I correct when use a surrogate in the APPLICATION entity? OR using composite of University_ID and Applicant_ID is a primary key?
Could APPLICATION entity be an associate entity? If it is, it could have some subtypes?
In ERD_2, how to show the ACCEPT relationship between APPLICANT and OFFER entity? AND how to show the MAKE relationship between UNIVERSITY and OFFER?
ERD_1
ERD_2
I would appreciate any help.
I can think of no reason why a weak entity could not be analyzed into subtypes (aka subclasses aka specializations). However, your two ERDs suggest that your analysis of your case is not one of specializations. In particular, in your first ERD, you use the word "has" to describe the relationship between an application and an interview or an offer.
"Has-a" relationships are typically not generalization-specialization relationships. "Is-a" relationships typically are. Example: An auto is a vehicle and a truck is a vehicle.
There is an entirely different issue here when it comes to what tables, columns, and constraints you will use to implement your model. That's a design issue rather than an analysis issue.
I don't understand your case well enough to agree or disagree with your analysis of your case.

How far can I take this database design?

I am interested in knowing the pros and cons of creating a custom system supported by a database like the one described below:
It has 6 tables that support it.
Entity: Lets say, anything "physical" that can exist and have detail stored against it
(Hilton Hotel, Tony Taxi, One Bar)
Entity Type: A grouping/type of entity
(Bar, Hotel, Restaurant)
Metadata: Any detail describing or belonging to an entity item
(IR232PH, foo#bar.com, 555-555-555)
Metadata Type: A grouping/type of metadata
(Post Code, Telephone, Email, address)
Entity Relationship: The ability to group any entity item to another
(Entity1-Entity2, Entity3)
Entity Relationship Type: The grouping/type of entity relationship.
I can see how this model is good for Entities that are similar but don't always have the same amount of attributes.
What are the pro/cons of using it as it is for entities as described?
An artist can be performing (relationship type) at a venue.
An artist can be supporting (relationship type) another artist
What would be the pro/cons of using it also to store more standard entities like users of the system?
A user can have a favourite (relationship type) venue/artist/bar etc
A user can have a attending (relationship type) event
Would you take it as far as having the news and blog posts in it?
This is highly subjective, but before I went up the abstraction ladder to where you are suggesting, I'd rather code my application to use DDL to modify the database schema to match the concrete aspects of the actual entities it was using, rather than having a static schema abstracted so far as to be able to store data about any potential entities.
In a way, to be a bit facetious, IMHO, what you are suggesting has already been done.... It is called a Relational Database. Every RDBMS is a software tool designed to be able to model any possible set of entities, and their attributes, in a way that accurately models those entities and the relationships between them.
Although you can certainly store the data in such a data model, there are a couple of problems (at least) with it.
The first problem is controlling the data. When an 'hotel' is described, what is the set of attributes and metadata that must be defined? Which metadata types can legitimately be entered for an hotel? Related to that is 'when I delete an hotel from the list, what else do I have to delete'? When I delete all hotels from the list (and I never want to store information about hotels again), what else do I have to delete? It is terrifically (terrifyingly?) easy to get all sorts of stray extraneous, unreferenced data into the database.
The second problem is retrieving the data. Suppose I want to know all the information about a specific hotel? How do I write a query for that? Actually, even inserting the data is hard, but selecting it is, if anything, harder. If I only want three attributes, it is easy - if the hotel actually has them all. It is harder if the hotel only has two of the three specified. But suppose the hotel has 30 atttributes, which is not a lot. Then it is terrifically difficult.
What you are describing is a souped-up version of a model known as the EAV or Entity-Attribute-Value model of data. It is generally accepted to be a 'bad idea', for all it is a common idea.
What you described is also known as a triplestore. A triple is a subject-object-predicate (Hotel HAS Rooms, Joe Likes HotelX, etc.). There are mechanisms for running these things (triplestore implementations), controlling the data (eg with ontologies) and for querying them, too (eg the SPARQL language). However, this is all fairly bleeding edge stuff and is known to have scalability problems. Nevertheless, combined with NoSQL approaches (index all your hotels in a big document store, etc.), it's an interesting area to keep an eye on.
See: http://en.wikipedia.org/wiki/Triplestore.

DDD/NHibernate Use of Aggregate root and impact on web design - ex. Editing children of aggregate root

Hopefully, this fictitious example will illustrate my problem:
Suppose you are writing a system which tracks complaints for a software product, as well as many other attributes about the product. In this case the SoftwareProduct is our aggregate root and Complaints are entities that only can exist as a child of the product. In other words, if the software product is removed from the system, so shall the complaints.
In the system, there is a dashboard like web page which displays many different aspects of a single SoftwareProduct. One section in the dashboard, displays a list of Complaints in a grid like fashion, showing only some very high level information for each complaint. When an admin type user chooses one of these complaints, they are directed to an edit screen which allows them to edit the detail of a single Complaint.
The question is: what is the best way for the edit screen to retrieve the single Complaint, so that it can be displayed for editing purposes? Keep in mind we have already established the SoftwareProduct as an aggregate root, therefore direct access to a Complaint should not be allowed. Also, the system is using NHibernate, so eager loading is an option, but my understanding is that even if a single Complaint is eager loaded via the SoftwareProduct, as soon as the Complaints collection is accessed the rest of the collection is loaded. So, how do you get the single Complaint through the SoftwareProduct without incurring the overhead of loading the entire Complaints collection?
This gets a bit into semantics and religiosity, but within the context of editing a complaint, the complaint is the root object. When you are editing a complaint, the parent object (software product) is unimportant. It is obviously an entity with a unique identity. Therefore you would would have a service/repository devoted to saving the updated complaint, etc.
Also, i think you're being a bit too negative. Complaints? How about "Comments"? Or "ConstructiveCriticisms"?
#Josh,
I don't agree with what you are saying even though I have noticed some people design their "Web" applications this way just for the sake of performance, and not based on the domain model itself.
I'm not a DDD expert either, but I'm sure you have read the traditional Order and OrderItem example. All DDD books say OrderItem belongs to the Order aggregate with Order being the aggregate root.
Based on what you are saying, OrderItem doesn't belong to Order aggregate anymore since the user may want to directly edit an OrderItem with Order being unimportant (just like editing a Complaing with its parents Software Product being unimportant). And you know if this approach is followed, none of the Order invariants could be enforced, which are extremely important when it comes to e-commerce systems.
Anyone has any better approaches?
Mosh
To answer your question:
Aggregates are used for the purpose of consistency. For example, if adding/modifying/deleting a child object from a parent (aggregate root) causes an invariant to break, then you need an aggregate there.
However, in your problem, I believe SoftwareProduct and Compliant belong to two separate aggregates, each being the root of their own aggregates. You don't need to load the SoftwareProject and all N Complaints assigned to it, just to add a new Complaint. To me, it doesn't seem that you have any business rules to be evaluated when adding a new Complaint.
So, in summary, create 2 different Repositories: SoftwareProductRepository and ComplaintRepository.
Also, when you delete a SoftwareProduct, you can use database relationships to cascade deletes and remove the associated Complaints. This should be done in your database for the purpose of data integrity. You don't need to control that in your Domain Model, unless you had other invariants apart from deleting linked objects.
Hope this helps,
Mosh
I am using NH for another business context but similar entity relationships like yours. I do not understand why do you say:
Keep in mind we have already
established the SoftwareProduct as an
aggregate root, therefore direct
access to a Complaint should not be
allowed
I have this in mine, Article and Publisher entities, if Publisher cease to exist, so do all the dependent Artcle entities. I allow myself to have direct access to the Article collections of each Publisher and individual entities. In the DB/Mapping of the Article class, Publisher is one of the members and cannot accept Null.
Care to elaborate the difference between yours and mine?
Sorry this is not a direct answer but too long to be added as a comment.
I agree with Mosh. Each ones of these two entities has its own aggregate root. Let me to explain it in the real life. suppose that a company has developed a software. There are some bug in this software, that made you annoy. you are going to go to the company and aware them from this problem. this company gives you a form to be filled by you.
This form has a field - section - indicates to the software name and description. additionally, it has some parts for your complaint. Is this form the same as the software manual? No. It is a form related to the software. It is not the software. Does this form has any ID? yes. It has. In other words, you can call the company in the next day and ask the operator about your letter of complaint. It is obvious that the operator will ask you about the Id.
This evidence shows that this form has its own entity and it could not be confused with the software itself. Any relation between two different entity does not mean one of them belongs to the other.

How do I validate the class diagram for a given domain?

I am working on car dealership business domain model/UML class diagram.
I am new to modeling, so I would like to know how to validate the class diagram. It's very important for me to have an appropriate, if not 100 percent correct, class diagram to use further development (use cases, etc.).
Is it possible to build a completely incorrect model? Or are there only appropriate and less appropriate models?
If I have a Customer associated with SalesTeam modeling a customer being served by SalesTeam, is that wrong? I have seen in examples of Customer being associated with Order, Order with ItemOrder and ItemOrder with ItemInventory. Where the SalesTeam or Staff is associated with Order.
How do I validate my model and relationships?
To validate domain models, do the following.
Write use cases. During the writing, make sure you're using nouns and verbs in a consistent way. To be sure that your nouns make sense, be sure to record notes in the domain model.
Walk through each use case, following along on your domain model. At the entities there? Relationships required for navigation? Attributes of each entity?
Since it's a domain model, try to avoid describing things as classes -- they're usually real-world entities.
For example "customer entity in direct relationship with sales team entity" is something you'll learn from the use cases. For example, customers are associated with orders, but the order is created by the sales team. So, you have two navigation paths between customer and order: direct and via the sales team. Both appear (to me) to be true.
You must compare your domain model with your use cases to be sure both agree.
The short answer is that this is not very important.
Use your domain class diagrams to keep a note of what you think is in the domain, that is all. It is not your god, and it will not hurt you to change it as you go.
Domain experts should help you to validate the domain model.
As far as validating the specific relationships, as you develop the model further and investigate the collaborations between objects you will discover more and different relationships. You will need to revisit the domain model often during your analysis and development.
I don't think it matters that it's 'correct' up front (i.e. before you move onto looking at use cases and further analysis), only that it is useful - it gives you a conceptual model of the problem and what the main classes involved are. It isn't going to be finished until the software is no longer being developed or maintained.
If it represents the way you view the problem right now, it's good enough for you to start further analysis. Revise it as your view of the problem changes and you learn more.