It is said that the Domain Model is used to capture the problem domain of an application. That's what are the requirements needed, etc. But often, these models are almost very close to what may turn out as classes during the implementation stage.
But there is also something called the Object-Oriented Domain Model, which is said to capture the "data abstraction of a problem domain". By the phrase "data abstraction of a problem domain", I understand it as the "layers of the problem domain that could be separated".
In this case, what's the difference between the Domain Model and an OO Domain Model? They both capture almost the same thing, aren't they?
Consider it like this; one critical component of OOP is the clustering of concerns; methods that operate on data should be grouped with that data. Frequently, a Domain Model will capture the problem domain, but because of problem domain "eccentricities", the Domain Model may not reflect an appropriate clustering of concerns. Object-Oriented Domain Modeling is simply a remapping of a Domain Model into an Object-Oriented (i.e., concern-clustered) model.
You're right that they capture the same thing, but the key is that the Domain Model is more concerned with purely representing the problem domain; the OODM is concerned with representing the problem domain in a manner that reflects appropriate OOP techniques.
Related
I am using strongly typed ids in my domain model, mostly following the guidance from Andrew Lock at:
https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-1/
These ids, e.g. ProductId, CustomerId, etc. are declared in the Domain Model.
My question is about exposing these to consumers of the Application layer. At the moment, an API controller could create a Command to send to the Application layer. These commands also needs to use Ids. My current implementation in the Command objects is use the primitive type, Guid, and then create a Strongly Typed Id when calling methods on the Domain Model.
However, it makes sense to extend the control offered by using strongly typed ids to communication between the API Controller and the Application Layer. But, I do not want my API Controllers to have a reference to the Domain Model (which is where the Strongly Typed Ids are declared at the moment).
How to go about this?
Declare a similar set of Strongly Typed Ids from the Application Layer. But this would still need a translation between the Application declaration and the Domain Model declaration before calling methods in the Domain.
Move the declaration of Ids into a 'public' module that both the API and Domain Model can reference. But this would mean some leakage of Domain Model dependencies to the API Controller dependencies and any change in my Domain Model approach may impact the API Controllers, which is not desirable.
The ask seems reasonable, but neither of the above solutions feel optimal. Any thoughts?
Having reviewed Vaughn Vernon's book "Implementing Domain-Driven Design":
https://www.amazon.co.uk/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577/ref=asc_df_0321834577/
I have followed the advice on page 580, which is basically "be pragmatic".
Specifically,
For Ids and any other value object that I consider pretty 'fixed' I have chosen to use a shared kernel that API, Application and Domain layers can use (i.e. option 2 from my question).
For other, potentially more complex, value objects that may contain additional business logic specific to the Domain and may be more volatile in response to business change, then I am using option 1 from my question and creating a slimmed down (DTO) version for exposing from the Application and performing mapping from those to the Domain Model versions.
I've read in the Patterns, Principles and Practices of DDD book that if you want to fully encapsulate your domain model you can make its properties private and use the Memento pattern to read them. There was also an example that a Repository gets a Snapshot of the domain model, then maps to a database model and saves its changes to the db. Also it retrieves the database model from db, maps it to the Snapshot and then uses the Factory pattern to reconstitute the Domain model from the Snapshot and work with it.
I am a bit confused about how much work is done here when you can just map the database model to the domain model, without using a factory or snapshots. Isn't this much easier?
If we are going to follow the book, is it the correct way to return the Domain model snapshot from the service layer to the presentation layer and then map it to a View Model? Or to create the snapshot in the presentation layer and pass it to service layer, using the factory pattern to reconstitute it there and then pass the domain model to the repository where it will again take its snapshot to map to the database model and save to the db....
Can you give some example when you need to use such complicated mapping architecture?
It really feels like you are writing complicated code when it can be done much simpler.
UPDATE
I can put code examples if it will be easier to understand what i am asking. ;)
A Repository's job is just to save and rehydrate domain entities from a persistent store. Any design pattern beyond that is just technical details, usually a way to work around ORM flaws - but it is not part of Repository (i.e. DDD's fundamental means of storage) per se.
I suppose the Memento pattern in that book is used to solve the "ORM / encapsulation conflict", i.e. an ORM needs write access to all of an entity's fields to be able to rehydrate it, which forces you to expose them and breaks encapsulation.
No, the Memento or Snapshot is for persistence purposes only. Service (or Application) layer maps from the real Entities or uses precomputed read-specific models if you're under CQRS.
What is Domain Model?
What is Object Model?
Are Domain Model and Object Model the same thing?
What is the difference between these two? Please explain with simple example. I'm new in this concepts. I searched a lot in Google. But I couldn't get any simple explanation and example.
An Object Model of a system is a collection of classes and objects describing the relationships between them and the properties and methods contained within, in terms of the Object Oriented principles : Abstraction, Encapsulation, Inheritance and Polymorphism.
A Domain Model is an Object Model describing the problem domain. They include the domain objects in the problem domain and describe the attributes, behavior and relationships between them.
If you talking about theses concepts according to DDD (Domain Driven Design), I don't agree with neigher of the preceding answers.
As the author pointed out in his book,
A domain model does not have to be an object model. There are MODEL-DRIVEN
DESIGNS implemented in Prolog, for example, with a model made up of logical rules
and facts.
So a Domain Model is a representation of you domain rules based on any paradigm, not necessarly should it be Object, it could be any other paradigm, but the most important about it, is that it must make domain concepts and rules clear and separated from other technical aspects.
In conclusion, we can say that an Object Model is one of the representation forms of a Domain Model
According to my understanding, Object Model only about Data Transfer Objects, just a mirror of database records without behaviors.
Entities in Domain Model have both Data and Behaviors that mimic the business rule. Domain Model not only include Classes but also Interfaces which have no meaning in Object Model.
Domain Model =>
For me, a domain model is a separate thing from any particular code or piece of software. If I come up with a domain model for something to do with restaurants, I could express my domain model on a piece of paper if I wanted to (or just inside my head). My domain model is a standalone conceptual entity, regardless of whether I actually end up writing any software based on it or not.
Object Model =>
The place where my domain model turns into actual code is in the object model. If my domain concepts include restaurant, order, and customer, then my object model will probably include objects like Restaurant, Order and Customer.
https://www.codewithjason.com/difference-domains-domain-models-object-models-domain-objects/
I'm trying to build my first CRUD application, and I don't understand if I should use an object containing getters and setters separated.
Considering that we have the Zend Framework Quick Start tutorial with a Model structure containing:
Gateway
DataMapper
Domain Object (model class)
If the Domain Object (as presented on Zend Quick Start Tutorial) consists of only getters and setters, is that an anti-pattern? In a sense, we are unecessarily dividing the domain object with a transaction script?
Please advise.
The Anemic Domain Model is an Anti-Patern ONLY IF you are trying to build a true Domain Model (aka Domain Model from Domain Driven Design) and end up with entities with only state and without behavior.
For a simple CRUD application an anemic domain model is probably a best practice, especially when you have framework that makes your job very easy.
See Martin Fowler's article about Anemic Domain Model and also Greg Young's Article.
The domain objects are seperated from the business logic of the software. This is an important idea of procedural programming.
However this pattern is considered to be a candidate for an anti-pattern by some developers which means that it might be a ineffective practice.
In fact you could consider disadvantages
your model is less expressive, getters and setters aren't really good to describe the model
code is harder to reuse, you get dublicated code among your transactional scripts
you have to use wrappers which hide the actual data structure (so maybe not really OOP)
there is always a global access to entities
I think the most interesting point to consider is that domain model's objects cannot assure their correctness at any time. Because their mutation takes place in seperated layers.
I worked on a CRUD application with zend framework too. The clear separation between logic and data is really great but when you progress you realize that the amount of layers and mappers gets bigger and bigger. Try to reuse your code as much as you can and avoid dublication.
Take this simple, contrived example:
UserRepository.GetAllUsers();
UserRepository.GetUserById();
Inevitably, I will have more complex "queries", such as:
//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();
I'm having trouble determining where the responsibility of the repository ends. GetActiveUsers() represents a simple "query". Does it belong in the repository?
How about something that involves a bit of logic, such as:
//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);
Repositories are responsible for the application-specific handling of sets of objects. This naturally covers queries as well as set modifications (insert/delete).
ActivateUser operates on a single object. That object needs to be retrieved, then modified. The repository is responsible for retrieving the object from the set; another class would be responsible for invoking the query and using the object.
These are all excellent questions to be asking. Being able to determine which of these you should use comes down to your experience and the problem you are working on.
I would suggest reading a book such as Fowler's patterns of enterprise architecture. In this book he discusses the patterns you mention. Most importantly though he assigns each pattern a responsibility. For instance domain logic can be put in either the Service or Domain layers. There are pros and cons associated with each.
If I decide to use a Service layer I assign the layer the role of handling Transactions and Authorization. I like to keep it 'thin' and have no domain logic in there. It becomes an API for my application. I keep all business logic with the domain objects. This includes algorithms and validation for the object. The repository retrieves and persists the domain objects. This may be a one to one mapping between database columns and domain properties for simple systems.
I think GetAtcitveUsers is ok for the Repository. You wouldnt want to retrieve all users from the database and figure out which ones are active in the application as this would lead to poor performance. If ActivateUser has business logic as you suggest, then that logic belongs in the domain object. Persisting the change is the responsibility of the Repository layer.
Hope this helps.
When building DDD projects I like to differentiate two responsibilities: a Repository and a Finder.
A Repository is responsible for storing aggregate roots and for retrieving them, but only for usage in command processing. By command processing I meant executing any action a user invoked.
A Finder is responsible for querying domain objects for purposes of UI, like grid views and details views.
I don't consider finders to be a part of domain model. The particular IXxxFinder interfaces are placed in presentation layer, not in the domain layer. Implementation of both IXxxRepository and IXxxFinder are placed in data access layer, possibly even in the same class.