Reputation: 179
the most common way to implement aggregates is to create a god class with enum status and "if-ladder", like below:
public class Order {
private OrderId id;
private PropertyA a;
private PropertyB b;
private OrderStatus status;
public void doSthWithA() {
if(status != OrderStatus.A) {
//throw illegal argument
}
//do sth with PropertyA
status = OrderStatus.B;
}
public void doSthWithB() {
if(status != OrderStatus.B) {
//throw illegal argument
}
//do sth with PropertyB
}
}
Order
class isn not coherent, because doSthWithA
uses PropertyA
and doSthWithB
uses PropertyB
.
Isn't better way doing it in this way:
public class OrderA {
private OrderId id;
private PropertyA a;
public OrderB doSthWithA() {
//do sth with PropertyA
return new OrderB(id);
}
}
public class OrderB {
private OrderId id;
private PropertyB b;
public void doSthWithB() {
//do sth with PropertyB
}
}
?
Anyway I have a question. We could persist both aggregates in one table ORDER
or two tables: ORDER_A
and ORDER_B
.
But what are strategies to test which order state is newest?
Let's assume that someone saves OrderA
to DB, next executes doSthWithA
and saves OrderB
to DB.
Futher when we do some query how could we resolve the newest state? Should we add some version or timestamp to aggregates?
And what about REST services?
With one god class Order
the REST services could look like:
/orders/{id}/do-sth-with-a
and
/orders/{id}/do-sith-with-b
With second solution could we have:
/a-orders/{id}/do-sth-with-a
and
/b-orders/{id}/do-sith-with-b
?
Upvotes: 0
Views: 40
Reputation: 57289
Isn't better way doing it in this way
Not necessarily better, because there are trade offs. However, it is common that the benefits of a design with smaller aggregates outweigh the costs.
Vaughn Vernon, in Implementing Domain Driven Design, proposes the rule "Design Small Aggregates".
Roughly, each aggregate "should" enclose coupled information; typically graphs of values that must be internally "consistent". If you find that your values form two discrete sets that have only a single identifier in common, that's a good sign that there is an opportunity to reduce the aggregate further.
We could persist both aggregates in one table ORDER or two tables: ORDER_A and ORDER_B. But what are strategies to test which order state is newest?
Real answer: if you actually care about "newest", then you should be modeling time in your domain logic.
It's not uncommon to throw general purpose timing information into a design, but you want to be careful about entangling general purpose timing used for operation and analysis from your domain timing.
And what about REST services?
Your resource model is not your domain model. Having a single "god" resource in your resource model has a completely different set of trade offs from "god" aggregates in your domain model.
It's completely normal to have one web resource that renders information from multiple aggregates.
Upvotes: 1