Passing CQRS commands directly to Domain objects - domain-driven-design

~TLDR: I'm implementing a CQRS + DDD solution for one of my larger projects, and, I'm wondering if there is any real reason that my command handlers can't directly dispatch the command objects to my aggregates, in a small handful of cases, where the command object is data rich? I can't find any specific reason why this would be any kind of an anti-pattern, and I can't find any opinions that go into great detail about this type of design.
Background: I have implemented CQRS systems before, and I have implemented DDD applications, but never CQRS + DDD in a proper Eric Evans style domain driven application. So I ask because I don't want to abuse my Aggregates, and hurt my application in the long term.
An example of my command object having quite a bit of data would be a registration command that takes in 8+ fields (firstname, lastname, preferred name, dob, title, username, password, department etc). It feels very awkward creating a method on my Aggregate that has 8 params, and the alternative solution of using some sort of dto, and having my handler map the command to the dto - either automagically using automapper, or inline - seems like an unnecessary and non value adding abstraction.
I can also see future use cases where commands might be data rich (it wouldn't be a large percentage of commands, but there would still be a few), so I'd like to get this seemingly trivial aspect correct from the start.

Command objects are usually expressed in primitive types while aggregate method signatures will be expressed in domain concepts.
The fact that you didn't immediately recognized that probably means that you missed a lot of opportunities to make implicit concepts explicit in your domain.
"a registration command that takes in 8+ fields (firstname, lastname,
preferred name, dob, title, username, password, department etc)"
What should strike you is that firstname and lastname could definitely form a meaningful whole, such as new FullName(firstname, lastname) and I'm sure there's a lot of other cases where Value Objects (VO) could or should be used in your domain... Username, Password, etc. ? Using VOs to model things that changes together will better describe your model as well as reduce the number of arguments you have to pass around.
Therefore, that makes command objects poor candidates as aggregate method arguments. If you go down that road, you will definitely miss modeling opportunities.

Agree with #plalx.
Take commands as aggregate method arguments may lead to having too many mapping codes inside aggregates: Mapping primitive types to domain objects, which is better to be placed out of the domain objects.
But for simpler projects, I think it is good starter.
In registration case, the bounded context is usually a supporting domain and the complexity usually comes from external integration(email notification, register with social accounts, etc). In this case, I think bounded context integration is more important than the models inside. So take commands as aggregate method arguments may be a quick start to get things done and saves your time to focus on your core domain.

Related

Are titles, labels and other UI-related things should be included in domain model?

I am confused about how to treat strictly UI-related things, that won't be used in the business logic in the domain model: how to properly store them in the database?
If for example I have an aggregate which is an entity and the main purpose of this model is to do something with an important thing, should I include a title in the model even though it does not contribute to the business logic in any way? Does it matter if I want to store the title in the same table I store other data for my entity (e.g. important things)?
#Entity
MyAggregate:
id: ID
title: str
importantThing: ImportantThing
def doSomethingWithImportantThing():
...
And if I don't include a title in the model, then how to properly store it using Repository pattern? If I keep the title within my model my Repository could look like so:
#Repository
MyAggregateRepository:
def create(myAggregate: MyAggregate):
...
What would happen to repository if I remove title from the model? Should it transform like so:
#Repository
MyAggregateRepository:
def create(myAggregate: MyAggregate, title: str):
...
The rule of thumb is to keep only things that are necessary for making decisions and protecting invariants inside the aggregate state. Otherwise, aggregates get polluted by alien concerns and convert to a messy one-to-one representation of an over-growing database table or document.
As any rule, it has exceptions. I don't think it's a good idea going overboard from the start and splitting the entity prematurely.
However, if you feel that things get messy and you can see patterns that a group of fields are used in a group of functions, while another group of fields is solely used in a different set of functions, you might get an idea that your aggregate deserves splitting.
The repository pattern is largely relevant for executing commands. Its main purpose is to handle the aggregate persistence. When implementing queries, consider using CQRS and write queries that you need to write, it doesn't have to be the repository that handles queries. Queries are also idempotent and have no side effect (except the performance), so it is rather safe not to think about the domain model as such when writing queries. It's better to name your queries using the Ubiquitous Language though.
Things that are purely UI-related typically don't belong in the domain unless the domain is related to managing UI-related items, such as in the case of a localisation domain.
Data that belongs in the domain would stay in the domain. For instance, if there is a comment on an AccountTransaction, or some such, then that would be in the language used by the users of the system and not something that one could localize. However, if that transaction has a Type indicator that is either Debit or Credit then you wouldn't want to necessarily use a string representation but rather codify that; even if the "code" is Debit and Credit or Dr/Cr. However, the front-end would use some l10n or i18n mechanism to display the text for the Type in the relevant language.
Hopefully I understood your question correctly.
Keep title within the bounds of your model. There are a few reasons for this.
The utility of title is kept within the bounds of the model itself, since it does not serve any other purpose in the domain layer. It serves as "identity" that is merely local to the model itself, and then gets surfaced in the UI.
The title is not necessary for creating the aggregate, since it has no business logic intent. If it did, it would represent a tighter coupling between the model and the creation of the aggregate, which is typically undesirable.
title seems to be an aggregate invariant that you'd only want the aggregate root to be concerned with, and not a concern from a perspective of external access or creation.
Ultimately, this keeps your design cleaner.

What is an Aggregate Root?

No, it is not a duplication question.
I have red many sources on the subject, but still I feel like I don't fully understand it.
This is the information I have so far (from multiple sources, be it articles, videos, etc...) about what is an Aggregate and Aggregate Root:
Aggregate is a collection of multiple Value Objects\Entity references and rules.
An Aggregate is always a command model (meant to change business state).
An Aggregate represents a single unit of (database - because essentialy the changes will be persisted) work, meaning it has to be consistent.
The Aggregate Root is the interface to the external world.
An Aggregate Root must have a globally unique identifier within the system
DDD suggests to have a Repository per Aggregate Root
A simple object from an aggregate can't be changed without its AR(Aggregate Root) knowing it
So with all that in mind, lets get to the part where I get confused:
in this site it says
The Aggregate Root is the interface to the external world. All interaction with an Aggregate is via the Aggregate Root. As such, an Aggregate Root MUST have a globally unique identifier within the system. Other Entites that are present in the Aggregate but are not Aggregate Roots require only a locally unique identifier, that is, an Id that is unique within the Aggregate.
But then, in this example I can see that an Aggregate Root is implemented by a static class called Transfer that acts as an Aggregate and a static function inside called TransferedRegistered that acts as an AR.
So the questions are:
How can it be that the function is an AR, if there must be a globaly unique identifier to it, and there isn't, reason being that its a function. what does have a globaly unique identifier is the Domain Event that this function produces.
Following question - How does an Aggregate Root looks like in code? is it the event? is it the entity that is returned? is it the function of the Aggregate class itself?
In the case that the Domain Event that the function returns is the AR (As stated that it has to have that globaly unique identifier), then how can we interact with this Aggregate? the first article clearly stated that all interaction with an Aggregate is by the AR, if the AR is an event, then we can do nothing but react on it.
Is it right to say that the aggregate has two main jobs:
Apply the needed changes based on the input it received and rules it knows
Return the needed data to be persisted from AR and/or need to be raised in a Domain Event from the AR
Please correct me on any of the bullet points in the beginning if some/all of them are wrong is some way or another and feel free to add more of them if I have missed any!
Thanks for clarifying things out!
I feel like I don't fully understand it.
That's not your fault. The literature sucks.
As best I can tell, the core ideas of implementing solutions using domain driven design came out of the world of Java circa 2003. So the patterns described by Evans in chapters 5 and six of the blue book were understood to be object oriented (in the Java sense) domain modeling done right.
Chapter 6, which discusses the aggregate pattern, is specifically about life cycle management; how do you create new entities in the domain model, how does the application find the right entity to interact with, and so on.
And so we have Factories, that allow you to create instances of domain entities, and Repositories, that provide an abstraction for retrieving a reference to a domain entity.
But there's a third riddle, which is this: what happens when you have some rule in your domain that requires synchronization between two entities in the domain? If you allow applications to talk to the entities in an uncoordinated fashion, then you may end up with inconsistencies in the data.
So the aggregate pattern is an answer to that; we organize the coordinated entities into graphs. With respect to change (and storage), the graph of entities becomes a single unit that the application is allowed to interact with.
The notion of the aggregate root is that the interface between the application and the graph should be one of the members of the graph. So the application shares information with the root entity, and then the root entity shares that information with the other members of the aggregate.
The aggregate root, being the entry point into the aggregate, plays the role of a coarse grained lock, ensuring that all of the changes to the aggregate members happen together.
It's not entirely wrong to think of this as a form of encapsulation -- to the application, the aggregate looks like a single entity (the root), with the rest of the complexity of the aggregate being hidden from view.
Now, over the past 15 years, there's been some semantic drift; people trying to adapt the pattern in ways that it better fits their problems, or better fits their preferred designs. So you have to exercise some care in designing how to translate the labels that they are using.
In simple terms an aggregate root (AR) is an entity that has a life-cycle of its own. To me this is the most important point. One AR cannot contain another AR but can reference it by Id or some value object (VO) containing at least the Id of the referenced AR. I tend to prefer to have an AR contain only other VOs instead of entities (YMMV). To this end the AR is responsible for consistency and variants w.r.t. the AR. Each VO can have its own invariants such as an EMailAddress requiring a valid e-mail format. Even if one were to call contained classes entities I will call that semantics since one could get the same thing done with a VO. A repository is responsible for AR persistence.
The example implementation you linked to is not something I would do or recommend. I followed some of the comments and I too, as one commenter alluded to, would rather use a domain service to perform something like a Transfer between two accounts. The registration of the transfer is not something that may necessarily be permitted and, as such, the domain service would be required to ensure the validity of the transfer. In fact, the registration of a transfer request would probably be a Journal in an accounting sense as that is my experience. Once the journal is approved it may attempt the actual transfer.
At some point in my DDD journey I thought that there has to be something wrong since it shouldn't be so difficult to understand aggregates. There are many opinions and interpretations w.r.t. to DDD and aggregates which is why it can get confusing. The other aspect is, in IMHO, that there is a fair amount of design involved that requires some creativity and which is based on an understanding of the domain itself. Creativity cannot be taught and design falls into the realm of tacit knowledge. The popular example of tacit knowledge is learning to ride a bike. Now, we can read all we want about how to ride a bike and it may or may not help much. Once we are on the bike and we teach ourselves to balance then we can make progress. Then there are people who end up doing absolutely crazy things on a bike and even if I read how to I don't think that I'll try :)
Keep practicing and modelling until it starts to make sense or until you feel comfortable with the model. If I recall correctly Eric Evans mentions in the Blue Book that it may take a couple of designs to get the model closer to what we need.
Keep in mind that Mike Mogosanu is using a event sourcing approach but in any case (without ES) his approach is very good to avoid unwanted artifacts in mainstream OOP languages.
How can it be that the function is an AR, if there must be a globaly unique identifier to it, and there isn't, reason being that
its a function. what does have a globaly unique identifier is the
Domain Event that this function produces.
TransferNumber acts as natural unique ID; there is also a GUID to avoid the need a full Value Object in some cases.
There is no unique ID state in the computer memory because it is an argument but think about it; why you want a globaly unique ID? It is just to locate the root element and its (non unique ID) childrens for persistence purposes (find, modify or delete it).
Order A has 2 order lines (1 and 2) while Order B has 4 order lines (1,2,3,4); the unique identifier of order lines is a composition of its ID and the Order ID: A1, B3, etc. It is just like relational schemas in relational databases.
So you need that ID just for persistence and the element that goes to persistence is a domain event expressing the changes; all the changes needed to keep consistency, so if you persist the domain event using the global unique ID to find in persistence what you have to modify the system will be in a consistent state.
You could do
var newTransfer = New Transfer(TransferNumber); //newTransfer is now an AG with a global unique ID
var changes = t.RegisterTransfer(Debit debit, Credit credit)
persistence.applyChanges(changes);
but what is the point of instantiate a object to create state in the computer memory if you are not going to do more than one thing with this object? It is pointless and most of OOP detractors use this kind of bad OOP design to criticize OOP and lean to functional programming.
Following question - How does an Aggregate Root looks like in code? is it the event? is it the entity that is returned? is it the function
of the Aggregate class itself?
It is the function itself. You can read in the post:
AR is a role , and the function is the implementation.
An Aggregate represents a single unit of work, meaning it has to be consistent. You can see how the function honors this. It is a single unit of work that keeps the system in a consistent state.
In the case that the Domain Event that the function returns is the AR (As stated that it has to have that globaly unique identifier),
then how can we interact with this Aggregate? the first article
clearly stated that all interaction with an Aggregate is by the AR, if
the AR is an event, then we can do nothing but react on it.
Answered above because the domain event is not the AR.
4 Is it right to say that the aggregate has two main jobs: Apply the
needed changes based on the input it received and rules it knows
Return the needed data to be persisted from AR and/or need to be
raised in a Domain Event from the AR
Yes; again, you can see how the static function honors this.
You could try to contat Mike Mogosanu. I am sure he could explain his approach better than me.

DDD: How to handle large collections

I'm currently designing a backend for a social networking-related application in REST. I'm very intrigued by the DDD principle. Now let's assume I have a User object who has a Collection of Friends. These can be thousands if the app and the user would become very successful. Every Friend would have some properties as well, it is basically a User.
Looking at the DDD Cargo application example, the fully expanded Cargo-object is stored and retrieved from the CargoRepository from time to time. WOW, if there is a list in the aggregate-root, over time this would trigger a OOM eventually. This is why there is pagination, and lazy-loading if you approach the problem from a data-centric point of view. But how could you cope with these large collections in a persistence-unaware DDD?
As #JefClaes mentioned in the comments: You need to determine whether your User AR indeed requires a collection of Friends.
Ownership does not necessarily imply that a collection is necessary.
Take an Order / OrderLine example. An OrderLine has no meaning without being part of an Order. However, the Customer that an Order belongs to does not have a collection of Orders. It may, possibly, have a collection of ActiveOrders if a customer is limited to a maximum number (or amount) iro active orders. Keeping a collection of historical orders would be unnecessary.
I suspect the large collection problem is not limited to DDD. If one were to receive an Order with many thousands of lines there may be design trade-offs but the order may much more likely be simply split into smaller orders.
In your case I would assert that the inclusion / exclusion of a Friend has very little to do with the consistency of the User AR.
Something to keep in mind is that as soon as you start using you domain model for querying your start running into weird sorts of problems. So always try to think in terms of some read/query model with a simple query interface that can access your data directly without using your domain model. This may simplify things.
So perhaps a Relationship AR may assist in this regard.
If some paging or optimization techniques are the part of your domain, it's nothing wrong to design domain classes with this ability.
Some solutions I've thought about
If User is aggregate root, you can populate your UserRepository with method GetUserWithFriends(int userId, int firstFriendNo, int lastFriendNo) encapsulating specific user object construction. In same way you can also populate user model with some counters and etc.
On the other side, it is possible to implement lazy loading for User instance's _friends field. Thus, User instance can itself decide which "part" of friends list to load.
Finally, you can use UserRepository to get all friends of certain user with respect to paging or other filtering conditions. It doesn't violate any DDD principles.
DDD is too big to talk that it's not for CRUD. Programming in a DDD way you should always take into account some technical limitations and adapt your domain to satisfy them.
Do not prematurely optimize. If you are afraid of large stress, then you have to benchmark your application and perform stress tests.
You need to have a table like so:
friends
id, user_id1, user_id2
to handle the n-m relation. Index your fields there.
Also, you need to be aware whether friends if symmetrical. If so, then you need a single row for two people if they are friends. If not, then you might have one row, showing that a user is friends with the other user. If the other person considers the first a friend as well, you need another row.
Lazy-loading can be achieved by hidden (AJAX) requests so users will have the impression that it is faster than it really is. However, I would not worry about such problems for now, as later you can migrate the content of the tables to a new structure which is unkown now due to the infinite possible evolutions of your project.
Your aggregate root can have a collection of different objects that will only contain a small subset of the information, as reference to the actual business objects. Then when needed, items can be used to fetch the entire information from the underlying repository.

Is this really DDD?

I am 80% sure I should not be asking this question because it might come across as negative and I mean no disrespect to anyone, especially the author of this book. I have seen several posts recommending this book and its companion project. I have not read the book, but I have spent a few hours today studying the project. And while it does look very complete, I am having a very hard time with how much the details of various things are scattered around. I am struggling in my own designs with how much I have to change if an entity changes, and this project does not make me very comfortable as a solution.
For example, there is a Employee object that inherits from a Person. Person has a constructor with first-name, last-name, etc. and therefore, so does Employee. Private to Employee are members for first name, last name, plus public properties for the same.
There is an EmployeeFactory that knows about both Employee and Person properties, as well as the SQL column names (to pull values from a reader).
There is an EmployeeRepository with unimplemented PersistNewItem and PersistUpdatedItem methods that I suspect, if implemented, would build SQL for INSERT and UPDATE statements like I see in CompanyRepository. These write the properties to strings to build the SQL.
There is a 'Data Contract' PersonContract with the same private members and public properties as Person, and an EmployeeContract that inherits from PersonContract like Employee does Person, with public properties mirroring the entities.
There is a static 'Converter' class with static methods that map entities to Contracts, including
EmployeeContract ToEmployeeContract(Employee employee)
which copies the fields from one to the other, including Person fields. There may be a companion method that goes the other way - not sure.
I think there are unit tests too.
In all I count 5-10 classes, methods, and constructors with detailed knowledge about entity properties. Perhaps they're auto-generated - not sure. If I needed to add a 'Salutation' or other property to Person, I would have to adjust all of these classes/methods? I'm sure I'd forget something.
Again, I mean no disrespect and this seems to be a very thorough, detailed example for the book. Is this how DDD is done?
Domain Driven Design is really simple. It says: make your Model classes mirror the real world. So if you have Employees, have an Employee class and make sure it contains the properties that give it its 'Employee-ness'.
The question you are asking is NOT about DDD, but rather about class architecture in general. I think you're correct to question some of the decisions about the classes you're looking at, but it's not related to DDD specifically. It's more related to OOP programming design patterns in general.
DDD s new enough (at least in some senses) that it may be a little early to say exactly "how it's done." The idea's been around for a fair long while, though, although we didn't make up a cool name for it.
In any case, the short answer (IMAO) is "yes, but...." The idea of doing a domain-driven design is to model the domain very explicitly. What you're looking at is a domain model, which is to say an object-oriented model that describes the problem domain in the problem domain's language. The idea is that a domain model, since it models the "real world", is relatively insensitive to change, and also tends to localize change. So, if for example your idea of what an Employee is changes, perhaps by adding a mailing address as well as a physical address, then those changes would be relatively localized.
Once you have that model, though, you have what I maintain are architectural decisions still to be made. For example, you have the unimplemented persistence layer, which might indeed be simply construction of SQL. It could also be a Hibernate layer, or use Python pickling, or even be something wild like a Google AppEngine distributed table structure.
The thing is, those decisions are made separately, and with other rationales, than the domain modeling decisions.
Something I've experimented with to some good result is doing the domain model in Python and then building a simulator with it instead of implementing the final system. That makes for something the customer can experiment with, and also potentially allows you to make quantitative estimates about the things the final implementation must determine.
to me, what makes DDD different from "mere" model-driven design is the notion of "aggregate roots", i.e. an application is only allowed to hold references to aggregate roots, and in general you will only have a repository for the aggregate root class, not the classes that the aggregate root uses
this cleans up the code considerably; the alternative is repositories for every model class, which is "merely" a layered design, not DDD

data access in DDD?

After reading Evan's and Nilsson's books I am still not sure how to manage Data access in a domain driven project. Should the CRUD methods be part of the repositories, i.e. OrderRepository.GetOrdersByCustomer(customer) or should they be part of the entities: Customer.GetOrders(). The latter approach seems more OO, but it will distribute Data Access for a single entity type among multiple objects, i.e. Customer.GetOrders(), Invoice.GetOrders(), ShipmentBatch.GetOrders() ,etc. What about Inserting and updating?
CRUD-ish methods should be part of the Repository...ish. But I think you should ask why you have a bunch of CRUD methods. What do they really do? What are they really for? If you actually call out the data access patterns your application uses I think it makes the repository a lot more useful and keeps you from having to do shotgun surgery when certain types of changes happen to your domain.
CustomerRepo.GetThoseWhoHaventPaidTheirBill()
// or
GetCustomer(new HaventPaidBillSpecification())
// is better than
foreach (var customer in GetCustomer()) {
/* logic leaking all over the floor */
}
"Save" type methods should also be part of the repository.
If you have aggregate roots, this keeps you from having a Repository explosion, or having logic spread out all over: You don't have 4 x # of entities data access patterns, just the ones you actually use on the aggregate roots.
That's my $.02.
DDD usually prefers the repository pattern over the active record pattern you hint at with Customer.Save.
One downside in the Active Record model is that it pretty much presumes a single persistence model, barring some particularly intrusive code (in most languages).
The repository interface is defined in the domain layer, but doesn't know whether your data is stored in a database or not. With the repository pattern, I can create an InMemoryRepository so that I can test domain logic in isolation, and use dependency injection in the application to have the service layer instantiate a SqlRepository, for example.
To many people, having a special repository just for testing sounds goofy, but if you use the repository model, you may find that you don't really need a database for your particular application; sometimes a simple FileRepository will do the trick. Wedding to yourself to a database before you know you need it is potentially limiting. Even if a database is necessary, it's a lot faster to run tests against an InMemoryRepository.
If you don't have much in the way of domain logic, you probably don't need DDD. ActiveRecord is quite suitable for a lot of problems, especially if you have mostly data and just a little bit of logic.
Let's step back for a second. Evans recommends that repositories return aggregate roots and not just entities. So assuming that your Customer is an aggregate root that includes Orders, then when you fetched the customer from its repository, the orders came along with it. You would access the orders by navigating the relationship from Customer to Orders.
customer.Orders;
So to answer your question, CRUD operations are present on aggregate root repositories.
CustomerRepository.Add(customer);
CustomerRepository.Get(customerID);
CustomerRepository.Save(customer);
CustomerRepository.Delete(customer);
I've done it both ways you are talking about, My preferred approach now is the persistent ignorant (or PONO -- Plain Ole' .Net Object) method where your domain classes are only worried about being domain classes. They do not know anything about how they are persisted or even if they are persisted. Of course you have to be pragmatic about this at times and allow for things such as an Id (but even then I just use a layer super type which has the Id so I can have a single point where things like default value live)
The main reason for this is that I strive to follow the principle of Single Responsibility. By following this principle I've found my code much more testable and maintainable. It's also much easier to make changes when they are needed since I only have one thing to think about.
One thing to be watchful of is the method bloat that repositories can suffer from. GetOrderbyCustomer.. GetAllOrders.. GetOrders30DaysOld.. etc etc. One good solution to this problem is to look at the Query Object pattern. And then your repositories can just take in a query object to execute.
I'd also strongly recommend looking into something like NHibernate. It includes a lot of the concepts that make Repositories so useful (Identity Map, Cache, Query objects..)
Even in a DDD, I would keep Data Access classes and routines separate from Entities.
Reasons are,
Testability improves
Separation of concerns and Modular design
More maintainable in the long run, as you add entities, routines
I am no expert, just my opinion.
The annoying thing with Nilsson's Applying DDD&P is that he always starts with "I wouldn't do that in a real-world-application but..." and then his example follows. Back to the topic: I think OrderRepository.GetOrdersByCustomer(customer) is the way to go, but there is also a discussion on the ALT.Net Mailing list (http://tech.groups.yahoo.com/group/altdotnet/) about DDD.

Resources