DDD + Event sourcing: inheritance and events

151 views
Skip to first unread message

Zach

unread,
May 21, 2013, 4:35:04 AM5/21/13
to ddd...@googlegroups.com
In my domain model, there are multiple type of credit transactions, that have complex life cycles.

Let's call them to simplify CreditType1, CreditType2 and CreditType3.
The thing is, all credit types share the same behavior, the only thing that changes is some displaying data, but that's not important here.

Some of the behaviors are:
  • We can "pay" a credit
  • We can "close" it
  • We can "extend" it
  • ...

So naturally, as the behaviors are exactly the same, I want to create an aggregate named Credit, and implement all the behaviors in methods pay(...), close(...).

These methods will generate events like: CreditPaid, CreditClosed, ...

Now there are other contexts that want to consume these events, and they need to react differently for each credit type.

There are two solutions that came to my mind:
  • Add a "Credit type" attribute (can be an enum for example) in the aggregate, that is not modifiable once set. Then pass it into all the events. This is simple, but that means that the other contexts will all have to do lots of if / else or switches each time they receive the event.
  • Use inheritance, by creating classes CreditType1, CreditType2 and CreditType3 that inherit from Credit. The behaviors are all the same, so by using some generics type we could just change the type of the events that are generated (e.g. CreditType1Paid, CreditType2Closed, ...). The consumers can then create handlers for each specific event, But the thing is that we will create a lot events and commands. If I have 10 events and 5 types, that makes me create 50 event classes, so that seems a good idea.
My opinion is that using the "Credit type" is much more simple, but I am scared that other developers (especially juniors) will implement some behaviors using this type.

It is highly probable that we need to customize one behavior for a particular type of transaction.

So I don't want to end up with code like this (this will happen trust me):
if type = 1 then
else if type = 2 then
...

Has anyone come with a better solution to implement this kind of scenario?

Thanks

Alexey Raga

unread,
May 25, 2013, 3:48:42 AM5/25/13
to ddd...@googlegroups.com
To me including extra info into events does not really make much sense. Today you need type, tomorrow you may want something else. You don't want to add more and more info into your events just because some other contexts want it in some cases.

When the "Credit" aggregate is created, it is created with a type of CreditType1, CreditType2, etc., right?

Could these other contexts that need to react to these events also subscribe to CreditCreated/whatever. events and internally keep all the info they need in order to make their decisions according to their business logic?
Because even if in one context you may have one Credit aggregate, in other contexts there may be an aggregate per CreditType, and they all may be very different...

So I would suggest:
- Context A publishes something like CreditCreated { Id, Type }
- Context B receives this event and creates its own aggregate, perhaps by type (as you said that the logic is very different)
- When other events are published by Context A (i.e. CreditPayed {Id}, etc), Context B only needs an ID to load its aggregate and call the behavior.

Hope it helps,
Alexey.
Reply all
Reply to author
Forward
0 new messages