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.
Related
I'm doing DDD analysis using event-storming, and run into this question:
Can we or should we define distinct events (e.g.: RouteCreatedByUser and RouteCreatedFromImport) based on how it was created?
Will "it depends" be the answer again? (e.g.: depends, if the way it was created will affect subsequent process / how the aggregate will be treated).
Or will the answer be flat out "no", just make one event (RouteCreated)?
You should always consider if your events have distinict business
significance. If they do, they should be separate. This allows them to
evolve independently.
Also, see how many things are common and how much is different. If you find some things which are different but not really generalisable, you should split the events. No use in having unused fields with lots of conditions when something is applicable and when it isn't.
If you fail to catch this distinction you would end up with low cohesion, lots of unused fields etc. Remember, that even sourcing is primarily about having an immutable event log. What it means is while you can modify the events if you need to do some simple schema migrations (in general, you shouldn't but sometimes it just makes more sense), you can never put any events in between or delete events.
Hi, I would like to have the receptionist and the manager to be able to view work type and rates and subsequently update it. However, tech personnel can only view but not update. Is the diagram valid?
I read that extended use-case are initiated by actors that initiated the base case. How should I differentiate that tech personnel can only initiate the base case and not the extended case? Should I not place the extension association? What about included use-case?
Sorry if this question has been asked before.
You should neither «include» nor «extend»
View work type and rates and Edit work type and rates are perfectly valid independent use cases.
In general it is a bad idea to chain use cases together just because you usually do one after the other.
You should not try to model the sequence of activities with use cases. Use your business process analysis for that.
You can use the post- and preconditions to constrain the execution of use case. In fact your Edit use case doesn't really require the View use case in particular to be executed does it?. It probably only needs a work type to be selected. So it can be executed right after any use case that has a postcondition stating that work type is selected.
Which use case does that is irrelevant to the Edit use case, as long as a work type is selected before the use case starts. There might be 10 different use cases that result in a work type being selected.
The «extend» I consider to be simply wrong. Extending use cases are usually incomplete use cases that insert their behavior into a complete use case are a particular extension point defined in the extended use case. The extended use case in does not have any knowledge about the extending use case and does not need or use the results of this behavior.
The few cases I which I found «extend» use cases to be applicable were things like monitoring use case. For example a use case that monitors the number of open tickets in the system and sends an alert to an admin in case a certain threshold is surpassed.
If you still insist on linking the use cases together, for example in case you really mean that you can only edit rates after executing the use case View work type and rates I would do it the other way around. Include the use case View work type and rates from the use case Edit work type and rates, probably as the first step.
Both solutions (separate use cases, or include from Edit to View) solve your issue regarding the rights of different users as it is now clear beyond any doubt who can do what.
I'd model it this way:
Manager and Receptionist have the same roles in this context which is why I used a generalization. Without knowing the domain this seems okay, but it's just a proposal.
The <<extend>> is constrained by {not allowed for actor Tech} which clearly excludes this actor from entering this (optional) use case.
There is no need to also associate Receptionist with Update... since it's an extension of View..., except you want to be able to Update without Viewing first.
N.B. about <<include>>/<<extend>>: They are not meant as chaining use cases. The UML spec states (pp. 638):
Extend is intended to be used when there is some additional behavior that should be added, possibly conditionally, to the behavior defined in one or more UseCases.
and
The Include relationship is intended to be used when there are common parts of the behavior of two or more UseCases. This common part is then extracted to a separate UseCase, to be included by all the base UseCases having this part in common.
Now that <<include>> just looks like a bastard. A use case is about a unique added value. And this uniqueness can be questioned if there were behavioral recurrence in more than one use case. In any case these relations are often just taken as functional decomposition. And that would be plain wrong. From my POV the UML spec would be better without these relations.
In context of the above diagram it represent a pattern where you view something and only then can make it editable. It would well be perfect to have two individual bubbles without <<extend>> where you place a constraint in Update telling { can only be reached after View... }.
I would change extend by include. To update the work, you have to view it. It is mandatory to view it.
In your diagram, Manager and Receptionnist are equivalent, with this schema only, you can define one actor only. Or model that Manager inherits from Receptionnist.
And to avoid mistake, if you do that, you have to be sure that Receptionist and Manager can also activate the view use case without the update. Otherwise some associations have to be remove.
Iam building bounded context using CQRS pattern. I prepared some queries and handlers for each. And now, in presentation layer(http REST controller) I have to use it. Question is, should I inject each handler to this controller (there is 4 queries and handlers) or use command bus and configure right handlers to specified query?
Well, either way seems like it makes sense; that's probably a hint that you should be passing in an interface that expresses the contract that the Controller needs satisfied, and punt the implementation details down a level.
My guess is that you ultimately won't want the controller directly wired into the query handlers, because that will restrict your options in a number of use cases (example: congestion control and back pressure). But you won't know until much further down the road, so keep things loose.
In the past we've injected some sort of Query Executor into the controller and passed queries into that. eg,
public SomeController(IQueryExecutor queryExecutor) { ...
and then
var results = queryExecutor.Query(new GetSomeThings(args..));
The handler for GetSomeThings is wired up by the supporting infrastructure so you don't need to inject those. Does that make sense?
A word of warning about CQRS/CQS:
If you find you writing queries and handlers that are used at most only once or twice, or commands that are dedicated to the controller that uses them, then perhaps CQRS/CQS is an abstraction you don't actually need to be paying the extra complexity cost for.
My teams and I have found this to be true on a number of projects. Often CQRS/CQS is just another unnecessary abstraction like a Repository which dispatches to an ORM lib or a 'Service' which has one or two line dispatches to a Repository, which...
Hopefully you get the point.
I like the Rule Of Three - don't try to get reusability until you have more than 3 usages. And even then, don't jump deep into something heavy and very prescribed like CQRS/CQS if you don't need it. DDD is very kool but you can pick and choose which elements of it make sense for you. Often much of it won't make sense when you apply pragmatic reasoning.
Just my 2 c.
I'm looking for insight/ papers/ articles, etc. whether a fully declarative Domain Model (as per DDD) is possible.
For example:
Validation can be declarative (lot's of ORMs do this)
business flow logic can be declarative: having a DSL for defining a workflow / Finite State Machine / process manager / DDD Saga (whatever you want to call it) on Crud-operations, through ddd-repositories most likely
decision logic can be declarative. I.e: most of the time this boils down to simple conditionals
derived / calculated fields could be done declaratively but is as bit tricky, especially when this cascades. I.e: you'd have to keep a dependency graph on the calculated fields, etc. Still it can be done.
Any links to people having actually tried that, or some convincing couter-arguments why this can't be done?
p.s.: Please don't answer with "Yes it can be done, since a FSM is Turing-complete with enough memory bla bla"
"Everything is a nail if you hold a hammer"
Instead of asking if it is possible - ask:
What are the reasons I want to do this particular thing declaratively?
Data validation is a nice thing to do declaratively. You have a DTO, you add some attibutes, everything is clear and readable.
Business flow done declaratively... Reminds me of a great failure of Windows Workflow Foundation. Is anyone actually using it?
What is the benefit of making a behaviour-centric components in a declarative way? Imperative way seems to be well-fitted to this.
Decision logic... maybe. But again - why?
"derived / calculated fields could be done declaratively but is as bit tricky"
Why do you want to do tricky things when there is a way of achieving the same result with straightforward things?
So why?
Do you need to change the behaviour of the app in runtime by editing some config file? OK, go for it.
Do you have a generic domain that will be used by many clients and you need some reconfiguration to fit them? Ok, but you need to clearly distinguish the unchangeable core of your domain and the varying stuff. Don't try to make all the things configurable - you'll end up with Inner Platform syndrome.
Do you believe you can make a declarative language your client could use to change his domain without a need for a programmer? No. You will fail. I know a language which was supposed to be like this. An easy, declarative language that ordinary accountants would use to explore their data. It's called SQL :D
I fully concur with Bartłomiej Szypelow's remark. Regardless, I will try to answer your question.
A declarative language always depends on an imperative language for it to work. Take something as simple as arithmetic for example. When we ask for the outcome of 1+1 we first need to know how the 1 should be understood and how in that context the + operator can be calculated before the statement as a whole can be interpreted. This is one of the ways we are able to overcome complexity; you don't need to know how a plus operation is done to be able to use one.
From http://en.wikipedia.org/wiki/Imperative_programming:
Procedural programming could be considered a step towards declarative
programming. A programmer can often tell, simply by looking at the
names, arguments and return types of procedures (and related
comments), what a particular procedure is supposed to do, without
necessarily looking at the details of how it achieves its result. At
the same time, a complete program is still imperative since it 'fixes'
the statements to be executed and their order of execution to a large
extent.
In any domain the same applies. If you ask the flight attendant to reschedule your flight she knows what a flight and a passenger is and how to reschedule one. Creating a fully declarative flight scheduling domain model without describing how scheduling works is therefore impossible. Since all domain models contain operations/behavior it is therefore equally impossible to create a domain model in a declarative language unless your problem domain is not unique, for example when you have three flight companies that operate in similar fashion.
Back to why... you said:
Actually, the hypothetical reason why is actually to allow non-coders
to create a (trivial) backend by configuration
Declarative programming is not always simpler than imperative programming. Most of the time people tend to think in outcomes, but sometimes the outcomes are so varied that it is (much) simpler to think in steps. This is the reason why these different styles exist and continue to exist in the first place. The main difference between a coder and a non-coder is not that a non-coder tends to think in terms of outcomes instead of processes, but that the non-coder simply does not want to be bothered with the workings of a computer. The non-coder wants to focus on the problem. Depending on the domain a non-coder may be helped best with an imperative DSL, instead of an declarative DSL.
I got a command : MovePlayerCommand.
One of the validator for this command does 3 things :
calculate the cost for the player to move (can be called for validation but also for displaying purpose)
validate this cost
listen to the "PlayerMoved" event so we can apply the costs (for instance - 10 action point).
Is this too much responsibilities for a single class ? If so how would you separate this ?
Edit : I know that removing the cost and checking it are 2 things, but I cant separate them from the computing of this costs, and I don't want to have 3 classes for each Action
There is a big misunderstanding here, as some poeple making comments seem to be mixing DDD and CQRS. The OP is talking about commands and has tagged the question with cqrs, so I am going to assume that the OP is indeed using DDD with CQRS.
The domain validation logic should be in the command handler, you can do, and indeed should do data checking before the command hits the handler stub, but not do any domain logic validation. That said, there is no other place where you could validate the command against the domain logic other than in the command handler because that is the place where your aggregates are loaded.
The validations you are showing are domain validations, so they should be actually performed by your aggregate, so yes, I think you should break that responsibility a bit, and split the different types of validation: data and domain.
Impossible to answer definitively without a lot more information.
That said, what you described does not sound like a validator; it sounds like a "calculator" of sorts.
It's likely that the calculating methods would belong in one class (the calculator class), and the validator class would then reference the calculator.
I tend to handle domain events in a very thin handler class, which then defers to an aggregate root or service (this is a common but not universal practice). So the root or service would likely also have a reference to the calculator (and possibly the validator).
This question may be too broad for SO, and might be better answered on a DDD forum. Even then, you may need to provide more background.