How to design, Order and State in DDD? - domain-driven-design

Supose I have an order and it can be in an state.
Order it would be the root entity, and State another root entity in the same bundary context than the order.
I was thinking that State it should be an entity too because it would be in this way:
State
{
long Id,
string State;
bool AllowModifyOrder;
bool AllowAceptorder;
//another properties that define what is possible to do in the state.
}
So I think it is needed that the State it is another entity, not a value object. But I am not sure if this it would be the best option.
Another doubt that I have is that the order need a property to point to the state, but not to the class, but to the ID, because I have read that an entity it is better to use the ID instead of the object, to avoid try to access or modify a root entity from another. But in this case, when I need some data of the state, for example if it can be accepted or if it can be modify. How could I do that if I only have the ID of the state?
Thanks.

Your State has to be a property of an Order because your Ubiquitous Language says "An Order can be in a state". You are tieing yourself too closely to the Database Model. That's why you have Id's and properties that look like Columns in your class.
If an Order has a State and there's a finite amount of States, then your State can be modeled as an Enum. Take this C# code for an example:
public Enum OrderState {
Draft,
Open,
Closed
}
public class Order {
OrderState State { get; private set; }
}
Your Repositories and Factories will take care of translating what you have in your Database and Inputs into Domain Classes like Order.

Related

Immutability in aggregate child entities

I have begun using domain driven design principles but are currently stuck with a specific problem.
I have an Aggregate which has multiple layers of nested child entities as shown below:
public class Aggregate: Entity<AggregateId>, IAggregateRoot {
private readonly List<ChildOne> childOnes;
}
public class ChildOne: Entity<ChildOneId> {
public string ChildOneValue1;
public string ChildOneValue2;
public string ChildOneValue3;
private readonly List<ChildTwo> childTwos;
}
public class ChildTwo: Entity<ChildTwoId> {
public string ChildTwoValue1;
public string ChildTwoValue2;
public string ChildTwoValue3;
}
In a domain service I need to access all values of ChildOne and ChildTwo including their ids.
public interface IDomainService {
public IEnumerable<INotification> Analyze(Aggregate aggregate);
}
However, I cannot return the entities as they are since this would violate the immutability principle.
This got me thinking that my domain model probably might not be optimal, but I cannot see how this can be different since the nested entities never can exist without the respective parent.
Another approach could be to have a single value object which holds all values of a given entity and then return this value object instead of the entity. But then a deep mapping needs to be performed since the domain service needs access to the values of all nested entities.
Any suggestions on to how to approach this?
Any suggestions on to how to approach this?
There are a couple of possibilities.
One is to invert your proposed API - design the domain service to accept immutable values as arguments, and then pass the instance of that service to the Aggregate, rather than the other way around.
public interface IDomainService {
public IEnumerable<INotification> Analyze(IEnumerable<DomainValue> values);
}
If you recall the Visitor pattern from the Gang of Four book, it is a very similar idea.
In some cases, an in-memory state machine might be a reasonable alternative to a stateless domain service. In that case, the API might look like
public interface IDomainService {
public void OnAnalyze(DomainValue value);
public IEnumerable<INotification> Notifications();
}
Another possibility is to design the Aggregate to act as a Collection
public class Aggregate {
// ...
public IEnumerable<DomainValue> YourCleverNameHere();
}
For use cases where you are not changing the state of the Aggregate, just leave the aggregate out of it, and work directly with an immutable in memory representation of the current state.
However, I cannot return the entities as they are since this would violate the immutability principle.
The entites don't need to be immutable. It's only value object that are immutable in tactical design of domain driven design.
As far as entities are aggregates are concerned, you should be able to get/save an aggregate from the repository only using the aggregate root. You should not be able to get/save an entity that is not an aggregate root.

DDD entity constructor parameters

If you have an entity with a value object as an attribute.
Which would be the parameters of the entity constructor, the value object? Or the primitive types of the value object?
First I did it building the value object outside the entity and I passed the value object to the entity constructor... but then I realized that maybe it would be the entity itself that has to build the value object.
I thought this because the entity and the value object are in fact an aggregate, and it is supposed that you have to access the inside of an aggregate through the aggregate root, i.e., through the entity.
So which is the right way? Is it allowed to deal with the value object outside the entity? Or the value object just can be used by the entity?
Thank you.
EDIT:
For example, I have an entity "Task" that is the aggregate root. This entity has a value object "DeliveryDate" (in format "dd/mm/yyyy hh:mm"). The entity has more value objects too.
class DeliveryDate extends ValueObject {
private String formattedDeliveryDate;
private DeliveryDate() {
super();
}
DeliveryDate ( String formattedDeliveryDate ) {
this();
this.setFormattedDeliveryDate ( formattedDeliveryDate );
}
private void setFormattedDeliveryDate ( String formattedDeliveryDate ) {
<< check that the string parameter "formattedDeliveryDate" is a valid date in format "dd/mm/yyyy hh:mm" >>
this.formattedDeliveryDate = formattedDeliveryDate;
}
........
The entity constructor:
Task ( TaskId taskId, Title title, Delivery deliveryDate, EmployeesList employeesList ) {
this();
this.setTaskId(taskId);
this.setTitle(title);
this.setDeliveryDate(deliveryDate);
this.setEmployeesList(employeesList);
}
My doubt is: Is this ok? (passing to the constructor the DeliveryDate object)
Or should I pass the string? (and the constructor creates the DeliveryDate object)
I think it's more a question of "should the outside of the aggregate know about the DeliveryDate concept?"
In general my doubt is about any value object of any entity, not just Task and DeliveryDate (this is just an example).
I have asked the question about the constructor, but it's valid for factories too (if the process of creating an instance is complicated)... should the aggregate factory parameter be the value object? or the primitives to create the value object?
In your case it might seem that the two solutions are similar. It doesn't really matter if you create the value object outside or inside of the entity. But think about when your entity will have more than one value object, the entity constructor will contain too much logic in order to make sure it creates the VOs correctly and at the same time enforce the entity's invariants.
One solution to avoid this unnecessary complexity is to use factories. The factory will abstract the creation process and this will keep you entity code simple.
In DDD, factories are very useful for creating aggregates. In the blue book there is a whole chapter about factories and here is good article about the use of factories in DDD http://culttt.com/2014/12/24/factories-domain-driven-design/
Edit
My doubt is: Is this ok? (passing to the constructor the DeliveryDate object) Or should I pass the string? (and the constructor creates the DeliveryDate object)
Yes, it is ok. Task should not know about how to create the value objects. You should not pass the strings cause that will add more complexity and responsibilities to the Task constructor.
I think it's more a question of "should the outside of the aggregate know about the DeliveryDate concept?"
Yes, it is not problems that the outside of the aggregate knows about the DeliveryDate. It is the same as knowing about strings and integer. Value objects are simple to deal with and reason about and they are part of the domain so I think there is no problems in dealing with them outside of the aggregate.
should the aggregate factory parameter be the value object? or the primitives to create the value object?
Here I would say the Factory should receive the primitive types and encapsulate the objects creation. cause if you pass the values objects to the factory it will just pass the same parameters to the Entity constructor and that is a middleman code smell.
Domain Driven Design doesn't offer any specific guidance here.
A common case might look something like this: we've retrieved a DTO from the database, and now want to create a Entity from it....
class Entity {
private Value v;
Entity (Value v) {
if (null == v) throw new IllegalArgumentException();
this.v = f;
}
Entity (DTO dto) {
this(new Value(dto));
}
// ...
}
Does it really matter if you invoke the second constructor rather than the first? Not much.
A language check:
DTOs are not retrieved from database. What you retreive from a database is an aggregate, not a DTO
I had to abandon that idea - that definition leads to too many problems.
For example, in event sourced designs, the database typically stores representations of events, not aggregates.
Even in traditional designs, it doesn't hold up -- the boundaries of your aggregates are defined by the constraints enforced by the domain model. Once you take the data out of the domain model, what you have left is just representations of state. Expressed another way, we save state in the database, but not behaviors, and not constraints -- you can't derive the constraints from the saved data, because you can't see the boundaries.
It's the model, not the database, that decides which data needs to be kept internally consistent.
I tend to use the term DTO because that's its role: to carry data between processes -- in this particular instance, between the data base and the domain model. If you wanted to use message or document instead, I wouldn't quibble.

Domain-Driven Design: how to model nested product category hierarchy? Even worse, what if the product category is an Aggregate Root?

I am practicing Domain-Driven Design so why not build a demo product catalog project? Apparently Product is the Core Domain here, but since I like to make the project more interesting, I would love to support nested Category hierarchy. In other words, a Category could have many child Category.
Moreover, I would want to separate Category from Product domain and make it its own Supporting Domain.
Question: Marking Category as AggregateRoot doesn't sound right to me. A Category could have many child Category, which are also AggregateRoots?!! How can I go about modeling this? Nested product category is pretty common in E-Commerce real life situation.
namespace DL.Demo.Domain.Shared
public abstract class ValueObjectBase<T> : IEquatable<T>
where T : ValueObjectBase<T>
{
public abstract bool Equals(T other);
public abstract override bool Equals(object obj);
public abstract override int GetHashCode();
}
public abstract class EntityBase : IEquatable<EntityBase>
{
public Guid Id { get; private set; }
protected EntityBase()
{
this.Id = Guid.NewGuid();
}
// Some Object overrides
}
And I actually have AggregateRoot inherents from Entity because I guess only an Entity could be an AggregateRoot?
public abstract class AggregateRoot : EntityBase
{
}
namespace DL.Demo.Domain.Catalog
public class Category : AggregateRoot
{
public string Name { get; private set; }
public Guid? ParentCategoryId { get; private set; }
public CategoryStatus CategoryStatus { get; private set; }
}
Having a nested list of AggregateRoot just doesn't sound right to me. If you don't mark the Category as the AggregateRoot, how would you go about modeling this?
I am new to DDD and all other related cool stuff like Domain Events, Event Sourcing, etc. I will be appreciated if somebody who had experience can tell me if I am going to the right way.
I am new to DDD and all other related cool stuff like Domain Events, Event Sourcing, etc. I will be appreciated if somebody who had experience can tell me if I am going to the right way.
You are on the right way.
Category should be an Aggregate root, with a reference to parent category by it's ID and this is very good.
Nested categories are a good candidate for event-sourcing, even if there are no special invariants to protect because of the different modes that this hierarchy could be projected in the Read models. You are not limited in any way on that representation, although the Aggregate is straight-forward. In every used Read model you could implement them differently as:
Model Tree Structures with Parent References
Model Tree Structures with Child References
Model Tree Structures with an Array of Ancestors
Model Tree Structures with Materialized Paths
Model Tree Structures with Nested Sets
See more here about implementing tree structures (this link points to MongoDB but that is not relevant).
The Category Aggregate just emits simple events as ACategoryWasCreated, ACategoryHasMovedToOtherParent and so on and the Read models just adapt to reflect those events.
I've implemented a tree structure like this and the queries on the read-side (the query side) are very very fast. You could select the products in a category and all child categories with no joins. Or you could build a category path, again, with no joins.
The key to defining an aggregate is to define first a transactional boundary. Outside of an aggregate boundary consistency is eventual - achieved by reacting to the domain events emitted by an aggregate.
Aggregate can hold another aggregate ID (Value Object) as a reference, however, is not responsible to be transactionally consistent with another aggregate.
So, the main question - Is your tree transactionally consistent? If yes, linked list won't scale well. You have to model it differently.
Modeling is context specific and is not cookie-cutter exercise. Maybe your category is just a value object that could be modeled as a path. Hard to say without broader context.
If you want to have a category tree, then the tree itself should probably be your aggregate root (I see you were coming to this conclusion on your own in the comments already). And this would have functions to add or remove children and so on.
And yes, with very large trees you could probably gain a lot of performance in having a read-only projection of your tree in for instance json format (stored in MongoDb, cache, file or whatever). Especially considering how such a category tree is typically updated only a tiny fraction of how often it is read, you could also easily get away with always just maintaining that json and foregoing a normalised database table tree altogether.

DDD repositories, and REST

Should DDD Repository always return aggregate and all it's value objects and entities?
For an example, I have Invoice object which has it's type and items.
Invoice
--Id
--Issuer
--InvoiceType
--Items
Data are persisted in 4 SQL Tables.
Invoices (FK to invoice type, FK to issuers),
InvoiceTypes
Items(fk to Invoice)
Issuers
If a repository should always return aggregates in it's full state, is it a bit of overkill to include InvoiceType and Items if i need to fetch 50 invoices, and display only ID and IssuerName.
Example for
InvoiceRepository
{
//should this also fetch InvoiceTypes and items from SQL, or i need separate invoice model for this
public List<Invoice> FetchForListing(int page, int take);
}
Should DDD Repository always return aggregate and all it's value objects and entities?
No. In use cases where you are going to be performing a write, you should load everything, because you need the full internal state to ensure that your change satisfies the invariant.
But if you are only going to perform a read, the full state isn't necessary at all -- it's reasonable to limit to the data you pull out.
(For example: when using the cqrs pattern, reads tend to not touch the aggregate at all, but instead copy data from "projections" of aggregate state into a more suitable representation.)
InvoiceRepository
{
// should this also fetch InvoiceTypes and items from SQL,
// or i need separate invoice model for this
public List<Invoice> FetchForListing(int page, int take);
}
So in this case, you wouldn't return a List<Invoice>, since that isn't what you want, and you might not use the same interface to represent the repository
InvoiceSummaryRepository
{
public List<InvoiceSummary> readSummary(int page, int take);
}
Check in your own ubiquitous language to figure out what InvoiceSummary is actually called, to determine whether List<InvoiceSummary> is actually a thing with a name of its own (likely is you are using it to build the representation of a resource in your REST api), and so on.

DDD - Problems in constructor and methods in entities design

I have a problem with regards to entity design. As I've read, when you design a DDD entity, the constructor should contain the values needed for an entity to "exist". For example, in the domain I am working on, a Class entity cannot exist without a Section and a Level:
public class Class
{
public Class(short id, string section, Level level)
{
ID = id;
Section = section;
Level = level;
}
//
// Properties
//
public short ID { get; private set; }
public string Section { get; private set; }
public Level Level { get; private set; }
//
// Methods
//
public static IList<Class> GetClassesByTeacher(short teacherID)
{
List<Class> classes = new List<Class>();
classes.Add(new Class(1, "a", null));
classes.Add(new Class(2, "b", null));
classes.Add(new Class(3, "c", null));
return classes;
}
}
Here Level is also an entity. As I am not yet finished in the design, Level's contructor might also contain an entity SchoolYear. What bothers me is for me to call GetClassesByTeacher method, I need to instantiate a Class along with other entities (Level, and also SchoolYear, needed in Level's constructor).
Is this the correct? I think it's bothersome when I just want to call the method. Are there other ways? I considered making it static but others said testability would suffer. I'm not sure if CQRS is one of the solution for what I want to do as I haven't yet read too much about it, but if it is, are there any other techniques aside from CQRS I can employ, or is it when going DDD, this is how it really is? Or is my entity design incorrect?
You should reconsider you domain model, as you actually say it seems there something wrong.
I may refer to Single Responsibility Principle (SRP) in which any class should have one one reason to change. In your example, what happens if we added a new field to 'Class', we will modify 'Class' it self and is right, but what happens if we decide that the listing should be on reversal order, or if you need a new type of list taking into account only interim teachers... you should change 'Class' but 'Class' has nothing to do with listings.
To answer you question, you might take a look at Repository pattern. Repositories are where you could ask for these type of listings.
I might split Class into two:
one for 'Class' model
other for 'Class' repositories
In summary:
public class Class
{
public Class(short id, string section, Level level)
{
ID = id;
Section = section;
Level = level;
}
//
// Properties
//
public short ID { get; private set; }
public string Section { get; private set; }
public Level Level { get; private set; }
}
public class ClassRepository
{
private IList<Class> contents;
//
// Methods
//
public IList<Class> GetClassesByTeacher(short teacherID)
{
List<Class> classes = new List<Class>();
for (Class elem: contents) {
if (elem.getTeacher().equals(teacherID) {
classes.Add(elem);
}
}
return classes;
}
}
repository = new ClassRepository;
level1 = new Level();
repository.Save(new Class(1, "a", level1));
repository.Save(new Class(2, "b", level1));
repository.Save(new Class(3, "c", level1));
result = repository.GetClassesByTeacher(1);
There are other details like using a ClassRepositoryInterface and implement with an InMemoryClassRepository, you will miss also Teacher information in class, as long as one one teacher drives the class, if not you might change how to filter by teacher, etc, etc.
I'm not a Java developer and the code will not compile but I expect you get the idea.
The GetClassesByTeacher method does indeed belong in some kind of repository or service class. Your Class entity is meant to represent an instance of that thing in the real world. An entity is not meant to provide instances (say, from some underlying persistence) - they are only meant to represent them. A ClassRepository would be a way to provide instances of the Class entity into your domain.
You also mentioned that Class cannot exist without a Level. You are speaking about aggregates here. There is a lot of DDD material online with regards to designing aggregates. Here are a couple:
DDD: Aggregates and Aggregate Roots
DDD: The Aggregate And Aggregate Root Explained
EDIT:
When an entity needs another entity to exist, should it always be an
aggregate?
No, just because entity A depends on entity B's existence, it doesn't mean that entity A needs to belong to entity B's aggregate.
As now I have a model in which many entities (like Class, Level,
Subject, Adviser, Teacher, etc.) exists only in a certain SchoolYear
(an entity). Is it OK for an aggregate to get that large?
An aggregate this large could result in performance and consistency issues.
Why performance? You could be loading a huge graph of data in memory for some aggregate root. You most likely only need to work on a fraction of that aggregate for whatever unit of work is occurring and not all the entities involved.
What consistency issues? The larger the aggregate, the more likely data can be changed in another part of the system while it has been retrieved into memory. When saving, data loss can occur.
Vaughn Vernon covers exactly these problems in his three-part Effective Aggregate Design series. It's a bit daunting if you aren't familiar with DDD lingo, but I highly recommend this read!
Also, by what you said, the Entity should not use the repository. If
some business logic in the Entity needs database access for it to be
processed, should it directly use DAL?
Entities should not know anything about repositories or services (or anything else, for that matter). They should not have any dependency on any other 'layer' in the system. Everything can know about your entities, but your entities shouldn't know about anything else. Provide me with an example of why you would want an entity to call on a repository and maybe I can provide a better answer.

Resources