How to choose the appropriate event abstraction level - domain-driven-design

I guess this question could be related to any evented system like Event sourcing / DDD / Lambda architecture, ESB, Actors... I tagged the question so that people experienced with these systems could answer.
I'm currently experimenting with my startup an original way to build user interfaces, by using concepts often used in DDD / Event sourcing world but applied to a javascript single page application. What I want is a purely functional UI, where I can replay the in-memory event log to restore the UI state (the event log is not persisted on browser close, it is just to make things easy to reason about and potentially enable cool features like UI undo/redo for free, time travelling debugger like in ELM...)
I just wonder sometimes how to choose the right level of abstraction for events as it seems to me there may be multiple "interpretations" of something that just happened.
Basically, in a JS SPA, many events are triggered after an user has clicked on a button, on a link or something like that. So I could add an entry to my event log being this low-level event (after managing to make it serializable). But this event can also be interpreted as a representation of what the user really has done in a high level abstraction.
To give an exemple, let's say I have on my UI a popup that is displayed at some point.
When the user clicks anywhere outside of the popup, it should be closed.
Let's imagine now the user clicks to a div outside of the popup to close it. What event abstraction level am I supposed to add to the event log?
User has clicked on div ?
User has clicked outside of the popup ?
User has closed the popup ?
These 3 event abstractions seems correct to me: they describe in the past something that happened, but at different abstraction levels. So I'm asking myself some questions like:
Do I have to choose one of the 3 abstraction level? If so how to choose?
Can or should I fire all 3 events? If so, wouldn't the event log becomes a bit messy?
Should I use concepts like DDD Saga, so that when receiving a "user clicked div" event, the Saga could fire a "close popup" command or something?

In an example described, I would suggest to not generate any events at all, because you are not performing any command (action which changes application state). You may want to have such event only in situation when there is actually a practical value of saving it, or you can think of it becoming valuable in the nearest future, so you can use all this information to generate some kind of report which will become valuable for your business.
There is no hard and fast rule behind that, it's just a matter of common sense. What kind of problem are you trying to solve? If it's implementing redo/undo, event sourcing is not the first thing that you should look for, "command" pattern would probably be a better choice. You will not get undo/redo "for free" with just event sourcing. Consider splitting your answer into multiple ones and be more specific about practical goal.
Also, my advice would be to stay away from SAGAs as long as you can. It's always better to perform things synchronously where possible, otherwise your code will quickly become a mess (less readable, growing semantic distance). If you have to make it async, the better alternative would be utilizing "continuation passing style","promises". Sagas should be considered as a last resort and used when all other approaches failed to work ... but such scenarios are more likely to crop up on a server side, when your lovely noSql thing does not support ACID transactions, for example :p.
Correct me if I'm wrong, but looks like you just want to play with a "new trendy approach" and try it without any practical reason. It's fine, as long as you are ok with making your application more complex than it should be. (more expensive to develop and support)

Related

Agile User Stories for Simulation Modeling Software

I'm new to Agile. I'm currently writing a software that basically does a simulation using real-life objects – for simplicity's sake here's an example:
I have a GUI where I can add two Human Object(s) onto a plane, a Ball Object, and one Human Object. Then I can press a PLAY button to simulate a situation where Human Object A can throw the Ball Object by specifying parameters I can use physics based on Force/Velocity/Direction, and then the Human Object B can catch the ball based on its own position and time while he is walking (where its movement is specified by reading in an input file).
It's a two step phase where I do parameter specification, then pressing play to simulate how those events unfold.
My difficulties reside only for the backend part where I know I need an a) Event Handler, b) Coordinate system infrastructure. But I'm having trouble determining where in my User Stories they should belong?
Right now they sit on its own User Story just written as tasks as "Event Handling." and "XYZ Coordinate System", which I feel is not very well placed.
What I'm trying to understand: If I have the User story:
As a user, I want to be able to be able to add a Human Object to my simulation so that I can have the object interact with the ball
Would my Task List (for specifically back-end stuff) include:
Implement xyz-coordinate system
Implement having an Event Handler and adding the Human Object to being an Event Handling object?
Or should I stick those tasks into a User Story like
As a user, I want to be able to see my objects interact with each other when I press a play button so that I can determine what the status of the objects are after it is done playing
to handle the task of implementing infrastructure of the coordinate system and event handling?
(And to note, in reality outside of the example, I have a lot more objects and back-end processing.)
The direct answer to your question is that the user story you put at the end is probably your best bet for a user story. Implementation tasks are just how your team is going to make that happen. Where it gets messy in complex work like what you are describing is if that user story takes a month to build and you have to break it down.
You want to deliver functionality, even if it isn't the whole package. This may be abusing your example, but where I'd probably start in the case you give is first limit the scope of the user story to simulating those exact objects and interactions: 2 humans and one ball. This takes out a lot of the variability. Now, from a programming standpoint, there is a huge trap here. When you implement it, make sure to do it in a way that those areas can be expanded later without throwing the implementation out and starting over if you can.
Next, if that is too big, I'd probably split the throw and the catch simulation. This is implementing the code in a way that is aligned with the purpose of Agile. If I make Human A throw a ball, I can show that to a user and potentially learn. Maybe we are simulating football and we throw a "prolate spheroid" (the term for the shape of an American football) in a perfect spiral. I show it to the user and he says "No no, we're from Spain, we are simulating an overhead 2-handed throw of a round ball." Now you've learned something critical about the work you've done and the work to be done (the receiver can't catch with their hands).
The specific tool of user stories may or may not be helpful. I could write this last one as "As a sports coach, I would like to simulate a throw-in so I can experiment with different techniques." That contains a lot of convenient information for me. In particular, user stories are most valuable in places where you are trying to understand your user's needs better. However, if you feel you understand them well enough, "Simulate throw" is a perfectly adequate backlog item.

In DDD: Commands that produce events that no one consumes

I am applying Domain driven design in my project and I am running into a scenario where a user action translates into a command in one of my bounded contexts and thus produces an event. However I see that none of my other bounded contexts would care about consuming this event. Essentially all this command is doing is saving/ updating state in my bounded context.
My questions are :
does a command have to produce an event ?
If so, does it matter that nobody is listening ?
does a command have to produce an event ?
Absolutely not.
If you were using event sourcing as your persistence strategy, then all of your changes of state would be "events". But there's no particular reason that you must expose the event elsewhere.
Hyrum's Law is one reason that you might prefer not to broadcast an event
With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody.
Don't guess what information should be included in the event until you have enough data at hand to make a good guess.
does it matter that nobody is listening ?
In an ideal world, not really -- in practice, costs may well figure into the decision.
It is not a necessity for a command to produce an event, though it is preferable.
One of the most significant benefits of events is the ability to generate the state of the system as on a particular date/time from scratch. If you were to religiously bubble-up events for all changes in the system, you will be able to apply events sequentially and bring the system to the state of your requirement.
IMHO, it does not matter that nobody is listening at that point in time. I am assuming that you are persisting your event into an event sink/log as part of your application. Doing so has two benefits:
a. If you were to discover a future requirement which would benefit from an event log, you are already a step ahead.
b. Even if nobody ever consumes the event, as mentioned in the first response, being able to generate a state of the system as on a particular date/time is a cool ability to have.
The pattern of persisting events and deriving a system state has its roots in Event Sourcing. You would want to take a deeper look at it to see its benefits.
does a command have to produce an event ?
No, its not a requirement, a command can just modify a state of an entity without dispatching an event. As said in others responses you should require every state change to produce a domain event if you use Event Sourcing.
If so, does it matter that nobody is listening ?
Yes and No.
Yes because there is no good or bad model, only useful model, if no one is listening then your modeling is not really useful to anyone.
No because domain event are called invariant, they reflect business event and change only when the business requirement change, and so they are part of your API (see the concept of published language).

Confused in Activity diagram notation

I have made an activity diagram for gym management, but i am facing a problem how will i connect Receptionist with Admin, According to requirement activity between Admin and receptionist takes place only through notification and i have made a signal and receptor for notification. Please also check if every notation is right and suggest me for modification?
I am sorry for not answering at once - several times had I looked at your picture, and, frightened, retreated.
You really tried and did something. It is good. But... You have put Use Cases directly into the activity diagram. So as is, it has no sense.
Let's take a customer. He has his swimlane. Good. According to your diagram, the customer comes and decides, what to do - immediately leave, join or inquiry. It doesn't matter, if he joins or inquiries, the result is common (why had he been choosing?) - he gives some unknown message to the receptionist. He never gets something back, never he does smth. else, he remains here and becomes immortal, because even his death won't finish his state of being here, waiting for some reaction from anybody. Poor man!
I don't think it is necessary to analyze here other swimlanes - they are even worse.
Better divide your work into levels.
Use Case diag. Define, who are actors (you have defined them well) and what are their interaction with system and its parts.
As the next stage you can make a deployment diagram - where are components of the system and maybe, actors, located and what messages they send to each other, defined.
And only now you can start with Activity diagram.
Also notice, that you'll have to return and correct the elders diagrams when you'll come to a dead end or some radical changes in the younger ones. You'll meet with both, be sure.
And when you have some problem with some diagram, come here, write down what you had BEFORE it (you didn't), what you have done on this stage (you did it) and we'll be able to help.

Non-Domain Model update in CQRS

In attempt to understand CQRS I created a small application which has Command Executor and event source. By my understanding the changes in domain model are triggered through commands. The domain model then generates the events to update the read model using denormalizer.
But in many cases there may be updates which are non-trivial for the domain. Like user changing his own profile picture. For requirements like these, what is the best way to implement?
I believe that using command will be overkill because the domain model as such doesn't change.
I tried to search for this question but didn't find the answer...
Don't mix CQRS and CRUD. Either the Bounded Context is suitable for CQRS or it's not. Your pet project probably isn't. But once you decide to apply the CQRS architecture style, you should stick with it.
Commands are trivial. And since you're already using Event Sourcing as well (which is not a prerequisite for CQRS btw.) you shouldn't bypass it for single use cases. Things rapidly become quite messy once you have multiple philosophies in place.
As far as directly writing to the Read Model goes: What if your Read Model goes out of synch, gets corrupted or must be modified and you have to rebuild it? If there's no related event, how should the Read Model know that something happened then?
There is one thing you can bypass if there's no domain behavior: You can just use a Transaction Script (POAA) in your command handler and publish the event from there without invoking the domain.
Long story short: You can happily mix styles in multiple isolated parts of your application (i.e. CQRS in one BC, CRUD in another) but inside a single BC you should stay consistent.

Naming Convention for Commands & Events

I'm just getting into event-driven architectures and would like to know what the convention is for naming commands and events. I know this much: Commands should be in the form DoSomething while events should be in the form SomethingHappened. What I need to clarify is if I need to append the word 'Command' to my commands and 'Event' to my events e.g. DoSomethingCommand as opposed to just DoSomething and SomethingHappenedEvent as opposed to just SomethingHappened. I would also like to know what the rationale is behind the community-preferred convention. Thanks!
The Command and Event suffixes are optional and are a matter of preference. I prefer to omit them and try to make the intent evident from the name alone. The most important aspect of naming commands and events is making sure they reflect the business domain more so than the technical domain. A lot of times terms like Create, Update, Add, Change are far too technical and have less meaning in the business domain. For example, instead of saying UpdateCustomerAddress you can say RelocateCustomer which could have a larger business context to it.
My convention is depending on namespaces and by that I mean that I never use the suffix Event nor Command.
I also organise commands and events into separate namespaces based on the aggregate type they are meant to affect.
Example:
// Commands
MyApp.Messages.Commands.Customers.Create
MyApp.Messages.Commands.Orders.Create
MyApp.Messages.Commands.Orders.AddProduct
// Events
MyApp.Messages.Events.Customers.Created
MyApp.Messages.Events.Orders.Created
MyApp.Messages.Events.Orders.ProductAdded
Depending on your requirements you might want to place your events into a separate assembly. The reason for this would be if you need to distribute events to downstream systems. In that case you probably don't want downstream systems to have to bother about your commands (because they shouldn't).
The convention that I've seen a lot and use myself is that events should be in past tense and described what happened:
UserRegistered
AccountActivated
ReplyPosted
Commands is something that you would like to do. So create names that illustrate that:
CreateUser
UppgradeUserAccount
As for organization, I usually put them together with the root aggregate that they are for. It makes it a lot easier to see what you can do and what kind of events that are generated.
That is, I create a namespace for each root aggregate and put everything under it (repository definition, events, commands).
MyApp.Core.Users
MyApp.Core.Posts
etc.
Commands and Events form a language for your application...an API. The use of terms like 'command' and 'event' are perhaps useful for system-level definitions where technical terms are meaningfully mixed into an entity's purpose, but if you are dealing with definitions for Domain behavior's, then drop the system/technical terminology and favor the business-speak. It will make your code read more naturally and lessen typing.
I started with the 'Command'/'Event' appendages but realized it was a waste of time and drew me away from the Ubiquitous Language DDD popularized.
HTH,
Mike
Appending Command and Event would be redundant information if yor commands/events are properly named. This would be noise that makes your code less readable. Remember Hungarian Notation? Most programmers (that I know of) don't use it anymore.

Resources