Domain Driven Design: When to make an Aggregate Root? - asp.net-mvc

I'm attempting to implement DDD for the first time with a ASP.NET MVC project and I'm struggling with a few things.
I have 2 related entities, a Company and a Supplier. My initial thought was that Company was an aggregate root and that Supplier was a value object for Company. So I have a Repository for company and none for Supplier.
But as I have started to build out my app, I ended up needing separate list, create, and update forms for the Supplier. The list was easy I could call Company.Suppliers, and create was horrible I could do Company.Suppliers.Add(supplier), but update is giving me a headache. Since I need just one entity and I can't exactly stick it in memory between forms, I ended up needing to refetch the company and all of the suppliers and find the one I needed to bind to it and again to modified it and persist it back to the db.
I really just needed to do a GetOne if I had a repository for Supplier. I could add some work arounds by adding a GetOneSupplier to my Company or CompanyRepository, but that seems junky.
So, I'm really wondering if it's actually a Value Object, and not a full domain entity itself.
tldr;
Is needing separate list/create/update view/pages a sign that an entity should be it's own root?

Based on your terminology I assume you are performing DDD based on Eric Evans' book. It sounds like you have already identified a problem with your initial go at modeling and you are right on.
You mention you thought of supplier as a Value Object... I suggest it is not. A Value Object is something primarily identified by its properties. For example, the date "September 30th, 2009" is a value object. Why? Because all date instances with a different month/day/year combo are different dates. All date instances with the same month/day/year combo are considered identical. We would never argue over swapping my "September 30th, 2009" for yours because they are the same :-)
An Entity on the other hand is primarily identified by its "ID". For example, bank accounts have IDs - they all have account numbers. If there are two accounts at a bank, each with $500, if their account numbers are different, so are they. Their properties (in this example, their balance) do not identify them or imply equality. I bet we would argue over swapping bank accounts even if their balances were the same :-)
So, in your example, I would consider a supplier an Entity, as I would presume each supplier is primarily identified by its ID rather than its properties. My own company shares its name with two others in the world - yet we are not all interchangeable.
I think your suggestion that if you need views for CRUDing an object then it is an Entity probably holds true as a rule of thumb, but you should focus more on what makes one object different from others: properties or ID.
Now as far as Aggregate Roots go, you want to focus on the lifecycle and access control of the objects. Consider that I have a blog with many posts each with many comments - where is/are the Aggregate Root(s)? Let's start with comments. Does it make sense to have a comment without a post? Would you create a comment, then go find a post and attach it to it? If you delete a post, would you keep its comments around? I suggest a post is an Aggregate Root with one "leaf" - comments. Now consider the blog itself - its relationship with its posts is similar to that between posts and comments. It too in my opinion is an Aggregate Root with one "leaf" - posts.
So in your example, is there a strong relationship between company and supplier whereby if you delete a company (I know... you probably only have one instance of company) you would also delete its suppliers? If you delete "Starbucks" (a coffee company in the US) do all its coffee bean suppliers cease to exist? This all depends on your domain and application, but I suggest more than likely neither of your Entities are Aggregate Roots, or perhaps a better way to think about them is that they are Aggregate Roots each with no "leaves" (nothing to aggregate). In other words, company does not control access to or control the lifecycle of suppliers. It simply has a one-to-many relationship with suppliers (or perhaps many-to-many).
This brings us to Repositories. A Repository is for storing and retrieving Aggregate Roots. You have two (technically they are not aggregating anything but its easier than saying "repositories store aggregate roots or entities that are not leaves in an aggregate"), therefore you need two Repositories. One for company and one for suppliers.
I hope this helps. Perhaps Eric Evans lurks around here and will tell me where I deviated from his paradigm.

Sounds like a no-brainer to me - Supplier should have its own repository. If there is any logical possibility that an entity could exist independently in the model then it should be a root entity, otherwise you'll just end up refactoring later on anyway, which is redundant work.
Root entities are always more flexible than value objects, despite the extra implementation work up front. I find that value objects in a model become rarer over time as the model evolves, and entities that remain value objects were usually the ones that you could logically constrain that way from day one.
If companies share suppliers then having supplier as a root entity removes data redundancy as well, as you do not duplicate the supplier definition per company but share the reference instead, and the association between Company and Supplier can be bi-directional as well, which may yield more benefits.

Related

How to Data model with NoSQL

I and my team are all beginners with NoSQL, were still wearing the Entity Framework with SQL Server 2008 on a project but with the passage of time the project was getting bigger and more complex than the EF does not resolve more for us, we decided to adopt the MongoDB, but we still have many doubts due to great paradigm shift, I'll post them here to see what you guys think and your opinions.
I have the entities "Person Fisica", "Patient" and "professional" and the patient and the Professional are Person, but in a few moments the patient and the professional will be the same person ex (a professional health unit which is also patient) in SQL Server we had a patient who had a reference to the Physical Person and professional who also had a reference to the PersonWhen Patient and Professional were the same person, the two had references to the same Person, now at mongo appeared doubts, some team members here want to do the same thing pretty much, Patient and professional organizations have the Id of the Person. Now I wanted to make the patient and the professional have the full object Person, but oh how would the integrity of this? Because technically the Physical Person of the Patient would be different from the Physical Person of professional ... This and other questions are breaking our heads here, in several entities that are shared do not know if we put the entity within the object that has it or the object only takes the Id of the entity, in the same way as in relational DB. Another example: the Health Unit and the types of UnidadeDeSaude, a type Of Health Unit has several Health Units and a Health Unit has a type, the correct approach would be to place the Unit Type object within the Health Unit or just reference it by Id?
Googled a few articles, but we're still in doubt in these cases
http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/
http://blog.fiesta.cc/post/11319522700/walkthrough-mongodb-data-modeling
Without being able to see exactly what you have, so speaking generally, in MongoDB you wouldn't JOIN tables in the same way you would with a RDBMS. Typically, if you have a Person entity you store the whole Person as a Person. This is a nice mapping from your code classes.
In the case where you have references to other entities, say where a single Person is shared between Patient and Professional you would do this with a foreign key reference in a RDBMS. You can do this with Mongo but Mongo won't do the JOIN for you. That would have be done by the caller. The recommended approach is to put a copy of the Person entity in both Patient AND Professional. The impact of this means that if you update the Person entity you now have to update the data in two places, but that's not necessarily as bad as it sounds. It's usually "quick" to update and you can update both 'atomically' so in practice there's little difference between that and updating a single entity except that you don't have to do the JOIN so your reads are simpler and usually faster.
The most powerful tool you have for fetching data is the Collection's (table's) index over your documents (entities) and any way you can leverage that will be the fastest way to return data. So counter intuitively, if you need to filter and process parts of a document more often than you need the whole, you are better to break it up into entities that share an indexed key. That would mean storing Person, Patient and Professional in the same collection and using two keys. One key is shared by the Person and it's derived class (Patient) and the other is a type discriminator that selects one part or the other. In other words, use the index to find whole entities, or collections of whole entities.
Aside from that, if once you have used the index to locate an entity, Person, Patient or Professional, read the whole entity and have it contain everything you need to fulfill the request without a JOIN. So whether you request the Patient or the Person (both refer to the same Person) you get the same Person data whichever object you read.
In short, you'll be replicating data in Mongo just about anywhere you'd have used a Join in SQL.
Are you able to draw what your class hierarchy looks like?

Performance issues with complex nested RoR reservation system

I'm designing a Ruby on Rails reservation system for our small tour agency. It needs to accommodate a number of things, and the table structure is becoming quite complex.
Has anyone encountered a similar problem before? What sort of issues might I come up against? And are performance/ validation likely to become issues?
In simple terms, I have a customer table, and a reservations table. When a customer contacts us with an enquiry, a reservation is set up, and related information added (e.g., paid/ invoiced, transport required, hotel required, etc).
So far so good, but this is where is gets complex. Under each reservation, a customer can book different packages (e.g. day trip, long tour, training course). These are sufficiently different, require specific information, and are limited in number, such that I feel they should each have a different model.
Also, a customer may have several people in his party. This would result in links between the customer table and the reservation table, as well as between the customer table and the package tables.
So, if customer A were to make a booking for a long trip for customers A,B and C, and a training course for customer B, it would look something like this.
CUSTOMERS TABLE
CustomerA
CustomerB
CustomerC
CustomerD
CustomerE
etc
RESERVATIONS TABLE
1. CustomerA
LONG TRIP BOOKINGS
CustomerA - Reservation_ID 1
CustomerB - Reservation_ID 1
CustomerC - Reservation_ID 1
TRAINING COURSE BOOKINGS
CustomerB - Reservation_ID 1
This is a very simplified example, and omits some detail. For example, there would be a model containing details of training courses, a model containing details of long trips, a model containing long trip schedules, etc. But this detail shouldn't affect my question.
What I'd like to know is:
1) are there any issues I should be aware of in linking the customer table to the reservations model, as well as to bookings models nested under reservations.
2) is this the best approach if I need to handle information about the reservation itself (including invoicing), as well as about the specific package bookings.
On the one hand this approach seems to be complex, but on the other, simplifying everything into a single package model does not appear to provide enough flexibility.
Please let me know if I haven't explained this issue very clearly, I'm happy to provide more information. Grateful for any ideas, suggestions or comments that would help me think through this rather complex database design.
Many thanks!
I have built a large reservation system for travel operators and wholesalers, and I can tell you that it isn't easy. There seems to be similarity yet still large differences in the kinds of product booked. Also, date-sensitivity is a large difference from other systems.
1) In respect to 'customers' I have typically used different models for representing different concepts. You really have:
a. Person / Company paying for the booking
b. Contact person for emergencies
c. People travelling
a & b seem like the same, but if you have an agent booking, then you might want to separate them.
I typically use a => 'customer' table, then some simple contact-fields for b, and finally for c use a 'passengers' table. These could be setup as different associations to the same model, but I think they are different enough, and I tend to separate them - perhaps use a common address/contact model.
2) I think this is fine, but depends on your needs. If you are building up itineraries for a traveller, then it makes sense to setup 'passengers' on the 'reservation', then for individual itinerary items, with links to which passenger is travelling on/using that item.
This is more complicated, and you must be careful to track dependencies, but the alternative is to not track passenger names, and simply assign quantities to each item (1xAdult, 2xChildren). This later method is great for small bookings, so it seems to depend on if your bookings are simple, or typically built up of longer itineraries.
other) In addition, in respect to different models for different product types, this can work well. However, there tends to be a lot of cross over, so some kind of common 'resource' model might be better -- or some other means of capturing common behaviour.
If I haven't answered your questions, please do ask more specific database design questions, or I can add more detail about specific examples of what I've found works well.
Good luck with the design!

SQL Relationships

I'm using MS SQL Server 2008R2, but I believe this is database agnostic.
I'm redesigning some of my sql structure, and I'm looking for the best way to set up 1 to many relationships.
I have 3 tables, Companies, Suppliers and Utilities, any of these can have a 1 to many relationship with another table called VanInfo.
A van info record can either belong to a company, supplier or utility.
I originally had a company_id in the VanInfo table that pointed to the company table, but then when I added suppliers, they needed vaninfo records as well, so I added another column in VanInfo for supplier_id, and set a constraint that either supplier_id or company_id was set and the other was null.
Now I've added Utilities, and now they need access to the VanInfo table, and I'm realizing that this is not the optimum structure.
What would be the proper way of setting up these relationships? Or should I just continue adding foreign keys to the VanInfo table? or set up some sort of cross reference table.
The application isn't technically live yet, but I want to make sure that this is set up using the best possible practices.
UPDATE:
Thank you for all the quick responses.
I've read all the suggestions, checked out all the links. My main criteria is something that would be easy to modify and maintain as clients requirements always tend to change without a lot of notice. After studying, research and planning, I'm thinking it is best to go with a cross reference table of sorts named Organizations, and 1 to 1 relationships between Companies/Utilities/Suppliers and the Organizations table, allowing a clean relationship to the Vaninfo table. This is going to be easy to maintain and still properly model my business objects.
With your example I would always go for 'some sort of cross reference table' - adding columns to the VanInfo table smells.
Ultimately you'll have more joins in your SP's but I think the overhead is worth it.
When you design a database you should not think about where the primary/foreign key goes because those are concepts that doesn’t belong to the design stage. I know it sound weird but you should not think about tables as well ! (you could implement your E/R model using XML/Files/Whatever
Sticking to E/R relationship design you should just indentify your entity (in your case Company/supplier/utilities/vanInfo) and then think about what kind of relationship there is between them(if there are any). For example you said the company can have one or more VanInfo but the Van Info can belong only to one Company. We are talking about a one – to- many relationship as you have already guessed. At this point when you “convert” you design model (a one-to many relationship) to a Database table you will know where to put the keys/ foreign keys. In the case of a one-to-Many relationship the foreign key should go to the “Many” side. In this case the van info will have a foreign keys to company (so the vaninfo table will contain the company id) . You have to follow this way for all the others tables
Have a look at the link below:
https://homepages.westminster.org.uk/it_new/BTEC%20Development/Advanced/Advanced%20Data%20Handling/ERdiagrams/build.htm
Consider making Com, Sup and Util PKs a GUID, this should be enough to solve the problem. However this sutiation may be a good indicator of poor database design, but to propose a different solution one should know more broad database context, i.e. that you are trying to achive. To me this seems like a VanInfo should be just a separate entity for each of the tables (yes, exact duplicate like Com_VanInfo, Sup_VanInfo etc), unless VanInfo isn't shared between this entities (then relationships should be inverted, i.e. Com, Sup and Util should contain FK for VanInfo).
Your database basically need normalization and I think you're database should be on its fifth normal form where you have two tables linked by one table. Please see this article, this will help you:
http://en.wikipedia.org/wiki/Fifth_normal_form
You may also want to see this, database normalization:
http://en.wikipedia.org/wiki/Database_normalization

Bad practice to have models made up of other models?

I have a situation where I have Model A that has a variety of properties. I have discovered that some of the properties are similar across other models. My thought was I could create Model B and Model C and have Model A be a composite with a Model B property and a Model C property.
Just trying to determine if this is the best way to handle this situation.
It's definitely valid in certain situations. Let's say you have a Person class and a Company class, and they have the common properties streetNumber, streetName, postcode, etc. It makes sense to make a new model class called Address that both Person and Company contain. Inheritance is the completely wrong way to go in such a situation.
When properties (e.g. state) are the elements of commonality, I definately tend towards using composition rather than inheritance. When using inheritance, its perhaps best to wait until behavior is the commonality, and overrides are needed now or imminently.
What you're looking at is creating an Aggregate Root. A core paradigm of the Domain Driven Design (DDD) principals.
Certain models in your app will appear to belong "at the top" or "as root" to other objects. For example in the case of customers you might have a Contact model which then contains a collection of ContactPoints (names, addresses, etc).
Or a Post (in the case of a blog), which contains a collection of Comments, a Tite, Body and a TagSet (for tagging). Notice how the items i've highlighted as objects - these are other model types as opposed to simple types (strings, ints, etc).
The trick will come when and how you decide to 'fill' these Aggregate Root trees/graphs. Ie. How will you query just for a single TagSet? Will you go to the top and get the corresponding Post first? Maybe you just wanted to rename the tag "aspnetmvc" to "asp.net-mvc" for all Posts so you want to cut in and just get the TagSet item.
The MVC Storefront tutorial has some good examples of this pattern. Take a look if you can.

Domain Driven Design, SOC, and entity identification

I've been trying to wrap my mind around DDD and how it can relate to MVC, but I'm having trouble with regards to entity identification.
In particular, I'm trying to maintain strict separation between my presentation, domain, and data models. My hangup here is in how I preserve entity identification across these boundaries. To clarify, I'm using separate classes to represent the same entity in different contexts - for example, I have a 'ShipmentRequest' domain class, several 'ShipmentRequestView' presentation classes (depending on the properties required by a particular view), and a 'shipment_request' database table (my data model).
I feel like using an 'ID' property (like ShipmentRequestId) would be a violation of the separation I'm trying to achieve, since this ID property is a database concern, and not a domain concern; and I don't want to pass the same object between layers, as this would mean passing unneeded data into my presentation layer.
How do I preserve this separation, and yet track identity between these layers?
Without the Id field in your entity you cannot map it to a database row. Therefore this id field even though it has nothing to do with your entities must leak into your domain model.
I feel it is most often overkill to use a presentation model, especially if what your are trying to achieve is hide some properties.
I think separation of concerns is mostly driven by the bounded context. For example, your Person, PersonView and Person table all seem the relate to a transaction processing context. In such a context I would make not even have a PersonView and the person table would be abstracted away.
On the other hand if you are in a reporting context, a PersonView would be more useful.
I think that the context is much more important than any layering scheme.
As for the lack of a natural key in your person entity, it could mean that Person is not really an entity. For exemple, in any real life application, there is always a number associated with the person: an employee has a employee number, a client as an account number, etc. This business id is definitely part of the domain.
I think having an "ID" field on entities is a concession a lot (most?) people end up making, and I wouldn't feel guilty for doing so.
As you say, even when you're not dealing with the database, you still need some notion of identity. You can try to come up with some kind of "natural" identity for each entity (a field like name, or a combination of several fields), but this isn't always possible. Even when it is, having an ID field often acts as a handy shortform for saying "the entity whose name is X, and whose date of birth is Y, and whose SSN is Z".
In the end, while arguably less "pure", having an ID field will likely simplify things a great deal.
Shipment Request is definitely a better example!
How will the users find a shipment request?
Depending on the answer you might need an id that users might remember, for example 20091012-A.
Can a shipment request id ever change?
If no, use the db key for identity.
Will you need to transfer shipment requests from one system to another?
If yes, do not use the db key for identity.
Whatever key you use you will need to make it available in the presentation model so that you can build links to actions on a particular shipment request.

Resources