Best practices to apply in Domain Driven Design principles? - domain-driven-design

Domain Driven Design can be really confusing at times and since I am rather new to this technique I would like to have some answers regarding those scenarios that are currently bugging me.
Here a simple diagram to represent my question using DDD principles. My question is about aggregate roots, domain validation and "ways to do" or best practices.
In this scenario, how would you implement a way to count the number of comments written by a user? Would it be a method in "Review"? Or would it be best to be a method in a repository (ReviewRepository)?
How do I make other entities access comments if they need to? Having this scenario, does that mean that Comment isn't part anymore of the "Review" aggregates?
What if comment have a composition relationship with some other entity? How would you manage the access to that entity? Is comment responsible of this entity or the root?
Any other suggestions or facts regarding this model? Any best practices I should fellow when designing a model?
Thanks.
NOTE: The answer must fellow DDD principles
There a little error in the Review entity. "Compte" in the Add method is "Account" and should be A instead of C.

In this scenario, how would you implement a way to count the number of comments written by an user ?
Responsibility belongs with review. It's an aggregate of comments. Count is a first-class feature of any aggregate.
How do i make others entities access comments if they need to ?
Comments are accessible via a Review. A Review is an aggregate of comments.
What if comment have a composition relationship with some other entity ?
"What if" questions are hard to answer without a concrete and specific example. After all, the design is driven by the problem domain, not random thoughts.
If some "other" entity also appears to be a composition of Comments, you have to go back to the domain experts and try to determine where the real responsibility lies.
One pair of question is "if the review is removed, what happens to the comments?" and "If the mysterious 'other' is removed, what happens to the comments?" This can help find the responsibilities.

Related

In DDD, is Comment included in Post Aggregate?

Sorry for poor English.
When learning about DDD , i have a question about aggregate.
In Board domain, we have two entity, One is Post, another is Comment.
I think Comment can't exist without Post. So I think Comment should be in Post Aggregate and Board domain has one aggregate which root is Post.
But from a different perspective, entities in the same aggregate have same life cycle,
so Comment life cycle is different from Post's life cycle,
and modifying Post doesn't affect Comment and vice versa.
So Board domain has two aggregate,
one is aggregate which root is Comment and another is aggregate which root is Post
This two think makes me feeling mess.
I've been there before, and I learned it the hard way. At first, it seems natural to have the comments part of the post aggregate but here are the limitations you might face with this design.
It can happen that you need to delete the post and keep the comments. Same as you see on some social media platforms.
A post can have a lot of comments to the point that it becomes expensive to load them all in memory each time you fetch a post.
Users can interact with comments directly (reactions, comment on a comment, share, mention other users ...) hence it is easier if the comment can be uniquely identified across the system.
You might need to list all comments of a user. It becomes harder when the comment is part of the post aggregate.
It is safer to have PostComment as a separate aggregate and keep a reference of the post. And as a general rule for designing aggregates, you should keep them as small as possible.
I recommend to read this brilliant article. That changes your perspective to aggregate design rules.
Effective Aggregate Design Part I: Modeling a Single Aggregate

Domain Driven Design: cross domain

In DDD, how to mix repositories ?
For example, a simple social network app where a personn write a post and mention someone.
Do the best way is to check if "the mentioned person" exist in user domain and throw a event for post domain for example ?
I think there are a lot of examples when a API need to mix domain.
I had read some article which explains to use event system.
Is the only solution ? I'm not looking for the best solution or a "pure ddd app".
First of all, there's no such thing as a "pure ddd app".
DDD is architecturally agnostic. There's no architectural style you must follow. It will only depends on the domain complexity of the context you're working on. For example, don’t be afraid to go with a CRUD‐style architecture if you are dealing with a context that contains no logic. Doing so, you'll be more in a DDD mindset than trying to apply things like Hexagonal/Onion/CQRS/EventSourcing and whatever good-looking architecture styles everywhere.
What you're describing in your question above is only related to the tactical part of DDD: what kind of code pattern would be nice to implement in order to solve my problem?
Let's say you have 2 different Bounded Context (see Stategic Patterns in DDD). One that deals with Users and one with Posts, as you mentioned above. As those are two separate contexts, they could have their own storage. In the Posts context, you could store a list of valid UserIDs that people can use when they want to mention someone. That way, you don't have to call any APIs to be sure that this UserID can be mentioned. In order to maintain this list, you also have many options. One could be to listen to events triggered by the Users context like UserSuscribed or UserUnsubscribed. Another option would be to give the responsibility to the Users context to call an API on the Posts context in order to add or delete UsersIDs.
In general, try to avoid coupling between your Bounded Contexts.

The meaning of "entity" in Domain-Driven Design

I attended a Webinar today by someone quite famous and respected author, lecturer, and expert in software engineering, architecture, and design. The webinar topic was "Incremental Architecture". This luminary stated that the concept of an entity in DDD has nothing to do with the concept of entity in databases. It was an unfortunate choice of term by Eric Evans in his original 2003 book. I was not satisfied with his explanation, and I find that his statement to potentially be very confusing to anyone trying to use DDD in design.
My question: what exactly does the term entity in DDD mean? - if it is not the very well understood and very well defined concept of entity in databases, ORM frameworks, JPA, development frameworks (Spring), etc.
Extensive research in software architecture.
This is a question about DDD strategic design. Coding is not involved.
Not relevant to my question. You allow a topic tag about DDD, which is a design approach, not a coding approach, yet you insist on having code-related questions. How is DDD related to coding?
My question: what exactly does the term entity in DDD mean?
Evan's defined entity in Chapter 5 (A Model Expressed in Software) of Domain Driven Design.
Entities (a.k.a. Reference Objects) ... are not fundamentally defined by their properties, but rather by a thread of continuity and identity.
An object defined primarily by its identity is called an ENTITY.
An ENTITY is anything that has continuity through a life cycle and distinctions independent of attributes that are important to the application's user.
It is an in memory abstraction of something that changes over time. It's a temporally varying membership function which for time t maps an identifier to some state. It's used within the domain model to represent things that change.
An example of a entity in a domain model might be... a question on stack overflow.
The meaning of "entity" in Domain-Driven Design
When somebody edits the text, or changes the title, or downvotes... it's still the same question, in that there's a progression from what the text used to be to what the text is now. It changes over time from having this text to having that text.
A simple entity in a domain model might map to a single row in a relational database, but it won't necessarily do so. More precisely, we might save the current state of the entity in a single row. But if that state includes a collection, then it is likely that the state will be distributed across multiple rows, perhaps in multiple tables.
You allow a topic tag about DDD, which is a design approach, not a coding approach, yet you insist on having code-related questions. How is DDD related to coding?
If The Source Code is The Design, then the design necessarily includes coding. The middle section of the Domain Driven Design book, which gets most of the attention, covers topics in modeling domains in code.
Truth be told: domain-driven-design turns up fewer questions with authoritative answers than, for example java.
An entity is a type that has an identity. The id could be anything but it has to be unique to the system and in fact depending on the subdomain you are in, the identity/entity might change.
For example:
A database might have a "User" Table that has fields "firstname", "lastname" e.t.c.
In DDD for an ecommerce application's purchase subdomain, you might have "Shoppers". These Shoppers might have an id of "firstname lastname". In the "Shipping" subdomain of the same application, you'll also have the concept of a "Shopper"(or buyer) but this time the identity of the shopper might be "Full address".
So, where a database entity is nothing more than a grouping of data with an identifier, A DDD entity is a concept. The concept is pertinent to the system, described in the ubiquitous language and is the central actor around which many functions in the domain will operate. The data that populates a DDD's entity usually comes from several datatable entities.

Search query and search result in DomainDrivenDesign

I have a web application with news posts. Those news posts should be searchable. In context of DDD what kind of buililng block are search query and search result?
These are my thoughts
They both don't have identity, therefore they are not Entities. But the absence of identity doesn't imply they are Value Object. As Eric Evans states:
However, if we think of this category of object as just the absence of identity, we haven't added much to our toolbox or vocabulary. In fact, these objects have characteristics of their own and their own significance to the model. These are the objects that describe things.
I would like to say that both are value objects, but I'm not sure. What confuses me are examples that I've found on Internet. Usualy value object are part of other entities, they are not "standalone". Martin Fowler gives for example Money or date range object. Adam Bien event compares them to enums.
If search result would be considered value object, that would be value object that consists of entities. I'm not sure that's completely alright.
I don't think they are DataTransferObject. Because we are not current concerned with transferring data between layers, but we are concerned with their meaning for the model in absence of layer.
I don't think search query is command. Because it's not a request for change.
As stated on CQRS
People request changes to the domain by sending commands.
I'm trying to use and learn DDD, can someone clarify this problem to me? Where did I go wrong with reasoning?
The simple answer is that querying is probably not part of your domain. The domain model is not there to serve queries, it is there to enforce invariants in your domain. Since by nature queries are read-only, there are no invariants to enforce, so why complicate things? I think where people usually go wrong with DDD is that they assume since they are "doing DDD" every aspect of the system must be handled by a domain model. DDD is there to help with the complex business rules and should only be applied when/where you actually have them. Also, you can and probably should have many models to support each bounded context. But that's another discussion.
It's interesting that you mention CQRS because what does that stand for? Command query responsibility segregation. So if commands use the domain model, and query responsibility is segregated from that, what does that tell you to do? The answer is, do whatever is easiest to query and display that data. If select * from news table filled to dataset works, go with that. If you prefer entity framework, go with that. There is no need to get the domain model involved for queries.
One last point I'd like to make is I think a lot of people struggle with DDD by applying it to situations where there aren't many business invariants to enforce and the domain model ends up looking a lot like the database. Be sure you are using the right tool for the job and not over complicating things. Also, you should only apply DDD in the areas of your system where these invariants exist. It's not an all or nothing scenario.

DDD Every Entitys seems fit inside one aggregate

I'm implementing a college system, and I'm trying to use DDD. I'm also reading the blue book. The basics entities of the system are Institution, Courses, Professors and Students. This system will allow a lot of Institutions, each having its courses, students and professors.
Reading about aggregates, all entities fits inside the aggregate Institution, because doesn't exists courses without Institution, the same for students and professors. Am I right thinking in that way?
In some place the professors will access the courses that they teach. Using this approach, should I always access the courses through Institution? This implementation seems strange to me, so I ask myself if Professor, as Students should be their own AR and have their Repository.
Even though you have accepted an answer I am adding this anyway since a comment is too short.
This whole aggregate root business trips up just about everyone when starting out with DDD. I know, since I have been there myself :)
As mentioned, a domain expert may be helpful in some cases but keep in mind that ownership does not imply containment. An Order typically belongs to a Customer but the Customer is not the AR for an Order since an Order can exist without a Customer. You may think: "But wait, that isn't really true!". This is where is comes down to rules. When I walk into a clothing store I can purchase a pair of shoes. I am a customer but they have no record of me other than a receipt I can produce. I am a cash customer. Perhaps my particular brand of shoe is not in stock but I can still order it. They will contact me once it arrives and that will probably be that and I'll in all likelihood still not be registered in any computer system. However, that same store is registered as a Customer with their supplier.
So why this long-winded story? Well, if it is possible to have an Entity stand alone with only a Value Object representing the owner then it is probably going to be an AR. I can include some basic customer information in a CustomerDetails value object in an Order? So the Order can be an AR.
No let's take a look at an OrderLine. Can I include some basic OrderDetails information on an OrderLine? This feels odd since a number of order lines constitute an Order. So it isn't quite as natural.
In the same way a GrapeBunch has to have a GrapeStem and a collection of GrapeBerry objects.
This seems to imply that if anything can be regarded as optional it may indicate that the related instance is an AR. If, however, a related instance is required then it is part of the AR.
These ideas are very broad but may serve as guidelines to consider your structure.
One more thing to remember is that an AR should not be instanced in another AR. Rather use the Id or a Value Object representing the relationship.
I think you're missing some transactional analysis - what typically changes together as part of the same business transaction, and how frequently ? One big aggregate is not necessarily a problem if only 2 users collaborate on it with only a few changes per day, but with dozens of concurrent modifications it could become a contention point.
Besides the data inventory and data structuration aspect of the problem, you want to have an idea of how the system will be used to make educated aggregate design decisions.
Something that might help you to separate those entities into different aggregate roots is to ask you: Which one of those must be used together? This is usually helpful as a first coarse filter.
So, for example, to add a student to a course, you don't need the Institution?
In your example about a professor accessing the courses he teaches. Can he access them by providing his professor id rather than the professor entity? I he provides the professor id, then the entities won't be associated by a reference but by an id.
Lots of this concepts have evolved a lot since the blue book was written 12 years ago. Even though the blue book is a really good book, I suggest you to also read the red book (Implementing Domain-Driven Design by Vaughn Vernon). This book has a more practical approach to DDD and shows more modern approaches, such as CQRS and Event Sourcing.
A professor and a student can exist in their own right, indeed they may associate themselves with institutions. An institution exists in its own right. A course may exist in its own right (what if the same course is offered at more that one institution, are they the same?)... The domain expert would best advise on that (infact they should advise and guide the entire design).
If you make an aggregate too big you will run in to concurrency issues that can avoided if you find the right model.
Some PDFs I recommend reading are here:
http://dddcommunity.org/library/vernon_2011/

Resources