Domain Driven Design, SOC, and entity identification - mapping

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.

Related

Best Way to Store Contextual Attributes in Core Data?

I am using Core Data to store objects. What is the most efficient possibility for me (i.e. best execution efficiency, least code required, greatest simplicity and greatest compatibility with existing functions/libraries/frameworks) to store different attribute values for each object depending on the context, knowing that the contexts cannot be pre-defined, will be legion and constantly edited by the user?
Example:
An Object is a Person (Potentially =Employer / =Employee)
Each person works for several other persons and has different titles in relation to their work relationships, and their title may change from one year to another (in case this detail matters: each person may also concomitantly employ one or several other persons, which is why a person is an employee but potentially also an employer)
So one attribute of my object would be “Title vs Employer vs Year Ended”
The best I could do with my current knowledge is save all three elements together as a string which would be an attribute value assigned to each object, and constantly parse that string to be able to use it, but this has the following (HUGE) disadvantages:
(1) Unduly Slowed Execution & Increased Energy Use. Using this contextual attribute is at the very core of my prospective App´s core function (so it would literally be used 10-100 times every minute). Having to constantly parse this information to be able to use it adds undue processing that I’d very much like to avoid
(2) Undue Coding Overhead. Saving this contextual attribute as a string will unduly make additional coding for me necessary each time I’ll use this central information (i.e. very often).
(3) Undue Complexity & Potential Incompatibility. It will also add undue complexity and by departing from the expected practice it will escape the advantages of Core Data.
What would be the most efficient way to achieve my intended purpose without the aforementioned disadvantages?
Taking your example, one option is to create an Employment entity, with attributes for the title and yearEnded and two (to-one) relationships to Person. One relationship represents the employer and the other represents the employee.
The inverse relationships are in both cases to-many. One represents the employments where the Person is the employee (so you might name it employmentsTaken) and the other relationship represents the employments where the Person is the Employer (so you might name it employmentsGiven).
Generalising, this is the solution recommended by Apple for many-many relationships which have attributes (see "Modelling a relationship based on its semantics" in their documentation).
Whether that will address all of the concerns listed in your question, I leave to your experimentation: if things are changing 10-100 times a minute, the overhead of fetch requests and creating/updating/deleting the intermediate (Employment) entity might be worse than your string representation.

Data model structure using autowire

what is the best approach to structure data model when using autowire? here is basic use case: i have domain data model on the backend which has case class User with fields id, username, active, auth_token which represents. This class maps to sql database table. On the frontend i only need fields id, username of User entity. I see only two approaches:
map User class to some FrontUser class with fields i need
divide database table on two separate which will be mapped to two different objects User and FrontUser
This is mostly a matter of opinion -- there's likely no One True Answer to it. But from this description I'd recommend simply having User and FrontUser. Dividing the database table usually introduces additional latencies and complexity to the code, whereas introducing a smaller case class for the API and front end is usually pretty small and easy -- possibly as little as a couple of lines of code. That seems likely to be easier both to write and maintain.

Breaking down a Core Data Entity

If I have an entity Person, and it has information like name, dateOfBirth, email and then it also has information like houseNo, street, landmark, city, country as well.
and this entity is representing a big form on an iPad.
Is it possible to break it down into smaller entities like Address ?
and then relate Address to Person, but that will be a one to one relationship, is it Okay ?
I am asking this because too many attribues based on one form for a person is becoming complex to manage.
You are encouraged to use a more entities to reflect the logic of your data model. This is certainly a good design principle and will provide more flexibility for future developments of your project.
However, I do not agree with your argument about complexity. In fact, a relational core data model is more complex than a flat one. Having one form referring to just one entity with a whole lot of attributes is certainly less complex than having relationships to other entities.
So if you think that your original data model is sufficient for your purposes, there is no good reason to change it.

Domain Driven Design: When to make an Aggregate Root?

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.

The Model in MVC

I am just starting on ASP.NET MVC trying to understand the philosophy first. I think I am pretty clear on the roles played by the controller and the view but I am a little confused on the model part. Some sources say its the domain model, some say its the data model, some say its the objects that are bound to the view.
IMHO these are very different things. So please can someone clear this up once and for all?
The model is "the domain-specific representation of the information on which the application operates". It's not just the data model, as that's a lower level than the MVC pattern thinks about, but (for example) it's the classes that encapsulate the data, and let you perform processing on them.
Scott Guthrie from MS uses this definition in his announcement:
"Models" in a MVC based application
are the components of the application
that are responsible for maintaining
state. Often this state is persisted
inside a database (for example: we
might have a Product class that is
used to represent order data from the
Products table inside SQL).
Further reading:
the MVC Wikipedia article
the MVC pattern on C2
I like to actually add an additional layer to make things clearer. Basically, the "Model" is the thing that is domain specific, and knows how to persist itself (assuming persistence is part of the domain).
IMO, the other layer I referred to I call the ViewModel ... sometimes, the "model" that gets passed to the view really has nothing to do with the domain ... it will have things like validation information, user display info, lookup list values for displaying in the view.
I think that's the disconnect you're having :-)
Your sources of advice are correct when they say it is the domain model. In many instances, it will be quite closely aligned your data model as well.
Where the domain and data models differ is that the data model is relatively static in form (not content) whereas your domain model adds the specific constraints and rules of your domain. For example, in my data model (database) I represent blood pressure as smallints (systolic and diastolic). In my domain model, I have a "blood pressure reading" object that holds values for each of the two readings and that also imposes additional restrictions on the range of acceptable values (e.g. the range for systolic is much smaller than that for smallints). It also adds qualitative judgments on these values (a BP of 150/90 is "high").
The addition of these aspects of the problem domain is what makes the domain model more than just the data model. In some domains (e.g. those that would be better rendered with a fully object-oriented data model and that map poorly on the relational model) you'll find that the two diverge quite significantly. However, all the systems I've created feature a very high degree of overlap. Indeed, I often push a fair number of domain constraints into the data model itself via stored procedures, user-defined types, etc.
You should have a look at this it a step by step tutorial.
From one of the chapters: page 26
In a model-view-controller framework the term “model” refers to the objects that represent the data of
the application, as well as the corresponding domain logic that integrates validation and business rules
with it. The model is in many ways the “heart” of an MVC-based application, and as we’ll see later
fundamentally drives the behavior of it.
Hope its useful.
For example, if you're building a web site to, say, manage operations of a nuclear plant, than the model is the model of the plant, complete with properties for current operating parameters (temperature etc.), methods to start/stop power generation, etc. Mmmm... in this case the model is a actually a projection of a real plant vs. an isolated mode but you got the idea.

Resources