3

Is it preferable to define a single 'container event' like below:

trait UserStatus
case object Active extends UserStatus
case object Inactive extends UserStatus

case class UserStatusChanged(newStatus: UserStatus, userId: String, eventTime: Long)

or define to multiple events:

case class UserBecameActive(userId: String, eventTime: Long)
case class UserBecameInactive(userId: String, eventTime: Long)

The first approach seems more maintainable by requiring less boilerplate to support additional user statuses, but the second seems more in the spirit of DDD and closer to the examples I've seen.

2
  • 1
    One could achieve both using polymorphism. E.g. UserBecameAcitve inherits from UserStatusChanged Nov 19, 2018 at 20:39
  • Is this a desktop app or a web application? Events are better suited for desktops. You could also consolidate similar events. In this case you might have UserActiveChanged(userId: string, isActive: boolean, eventTime: Long) But again, it really matters what you intend to do with those events. In C# desktop apps, you have a PropertyChangedEvent(source: object, property: string) and it is up to the listener to know what to do with that event. It would cover any changes to your user state, not just whether it is active or not. It's meant for binding values to other objects. Apr 21, 2019 at 12:59

3 Answers 3

1

Whether you go the first or the second way depends entirely on your needs. If you are only ever interested about the situation when a user becomes active and couldn't care less about them becoming inactive, defining only the UserBecameActive event and dispatching it to your system when a user is activated would be the recommended way to go. After all, why define the UserStatusChanged for all status types if you will only ever react to this even when the value of the newStatus property is in fact Active? That's just another if/else in your code. Thanks to this you can then define event handlers reacting to this event type and perform additional logic when such even occurs within your system, without the need to inspect the potential UserStatusChanged values to know whether the user is active or not. Not to mention, UserBecameActive probably fits way better in your ubiquitous language than the UserStatusChanged event.

On the other hand, having too granular approach won't most likely solve all your problems either. If you start introducing many event types for each property (or a thing of significance) of an entity, you will most likely come across a situation where you could use having multiple attributes of the event but then the event wouldn't play nicely in your domain. So then perhaps event having just a simple UserHasBeenUpdated event could be perfectly reasonable.

0

There are two possible definitions of events here and they should be treated differently. If you’re talking about a DDD event within a domain, I would go with the two distinct events. Domain Events should indicate something significant is happening and needs to be addressed. There’s an expectation that something within the domain will handle that event appropriately. When you create a Domain Event, you should have a handler specifically in mind. Note that this means if there's code that needs to handle any state change regardless of new value you would also need the UserStatusChanged.

If you are talking about what events to store in an Event Store, I would go with the generic UserStatusChanged. These events should not incorporate domain logic, they only reflect state changes in your domain. If you limit to UserBecameActive and UserBecameInactive you are implying those are the only two states that are significant. I understand those are probably the only two states that exist at the moment, but what happens when a third is added (such as “Membership Pending”). Do you now add a third event? What about the code that doesn’t care what the UserStatus value is, just that it changed (caching algorithms come to mind)? For Event Store Events, you do not need to have a specific handler in mind.

Event store events should say “something changed” not “something changed to an important value”. That’s up to the domain to decide.

Domain events should say "something significant is happening" regardless of whether that involves a state change or not.

0

I would go definitely for two distinct events.

For the reason I like my events to be explicit, instead of implicit (e.g. I have to check for a property within the event class VS I see what type of event has been thrown by looking at the class name).

Also it makes queries in event store more easy if you look for a particular event.

Eventually the question you should ask yourself is the following:

As a business owner / business analyst, what is speaking the most to me ? the former form or the two distinct events ?

Not the answer you're looking for? Browse other questions tagged or ask your own question.