How to keep domain model pure using ES approach? - domain-driven-design

I have flicked through few popular Event Sourcing frameworks written in a variety of different common languages. I have got the impression all of them affect the domain models to a really high degree. As far as I understand ES is just an infrastructure concern - a way of persisting aggregate state. Of course, it facilitates message driven inter-context integration but in core domain's point of view is negligible. I consider commands and events to be part of the domain itself so it looks perfectly fine that aggregate creates events (but not publishes them) or handles commands.
The problem is that all of DDD building blocks tend to be polluted by ES framework. Events must inherit from some base class. Aggregates at least are supposed to implement foreign interfaces. I wonder if domain models should be even aware of using ES approach within an application. In my opinion, even necessity of providing apply() methods indicates that other layer shapes our domain.
How you approach this issue in your projects?

My answer applies only when CQRS is involved (write and read models are split and they communicate using domain events).
As far as I understand ES is just an infrastructure concern - a way of persisting aggregate state
Event sourcing is indeed an infrastructure concern, a kind of repository but event-based Aggregates are not. I consider them to be an architectural style, different from the classical style.
So, the fact that an Aggregate, in reaction to an command, generates zero or more domain events that are applied onto itself in order to build its internal (private) state used to decide what events to generate in the future is just a different mode of thinking and designing an Aggregate. This is a perfect valid style, along with classical style (the one not using events but only objects) or functional programming style.
Event sourcing just means that every time a command reaches an Aggregate, its entire internal state is rebuild instead of being loaded from a flat persistence. Of course there are other huge advantages (!) but they do not affect the design of an Aggregate.
... but not publishes them ...
I like the frameworks that permit us to just return (or better yield - Aggregate's command methods are just generators!) the events.
Events must inherit from some base class
It's sad that some frameworks require that but this is not necessarily. In general, a framework needs one mean of detecting an event class. However, they can be implemented to detect an event by other means instead of using marker interfaces. For example, the client (as in YOU) could provide a filter method that rejects non-event classes.
However, there is one thing that I couldn't avoid in my framework (yes, I know, I'm guilty, I have one): the Command interface with only one method: getAggregateId.
Aggregates at least are supposed to implement foreign interfaces.
Again, like with events, this is not a necessity. A framework could be given a custom client event-applier-on-aggregates function or a convention can be used (i.e. all event-applier methods have the form applyEventClassNameOrType.
I wonder if domain models should be even aware of using ES approach within an application
Of ES not, but event-based YES, so the apply method must still exists.

As far as I understand ES is just an infrastructure concern - a way of persisting aggregate state.
No, events are really core to the domain model.
Technically, you could store diffs in a domain agnostic way. For example, you could look at an aggregate and say "here is the representation before the change, here is the representation after, we'll compute the difference and store that.
The difference between patches and events is the fact that you switch from a domain agnostic spelling to a domain specific spelling. Doing that is normally going to require being intimate with the domain model itself.
The problem is that all of DDD building blocks tend to be polluted by ES framework.
Yup, there's a lot of crap framework in the examples you find in the wild. Sturgeon's Law at work.
Thinking about the domain model from a functional perspective can help a lot. At it's core, the most general form of the model is a function that accepts current state as an input, and returns a list of events as the output.
List<Event> change(State current)
From there, if you want to save current state, you just wrap this function in something that knows how to do the fold
State current = ...
List<Event> events = change(current)
State updated = State.fold(current, events)
Similarly, you can get current state by folding over the previous history
List<Event> savedHistory = ...
State current = State.reduce(savedHistory)
List<Event> events = change(current)
State updated = State.fold(current, events)
Another way of saying the same thing; the "events" are already there in your (not event sourced) domain model -- they are just implicit. If there is business value in tracking those events, then you should replace the implementation of your domain model with one that makes those events explicit. Then you can decide which persisted representation to use independent of the domain model.
Core of my problem is that domain Event inherits from framework Event and aggregate implements some foreign interface (from framework). How to avoid this?
There are a couple of possibilities.
1) Roll your own: take a close look at the framework -- what is it really buying you? If your answer is "not much", then maybe you can do without it.
From what I've seen, the "win" of these frameworks tends to be in taking a heterogeneous collection of events and managing the routing for you. That's not nothing -- but it's a bit magic, and you might be happier having that code explicit, rather than relying on implicit framework magic
2) Suck it up: if the framework is unobtrusive, then it may be more practical to accept the tradeoffs that it imposes and live with them. To some degree, event frameworks are like object relational mappers or databases; sure, in theory you should be able to change them out freely. In practice? how often do you derive benefit from the investment in that flexibility
3) Interfaces: if you squint a little bit, you can see that your domain behaviors don't usually depend on in memory representations, but instead on the algebra of the domain itself.
For example, in the domain model, we deposit Money into an Account updating its Balance. We don't typically care whether those are integers, or longs, or floats, or JSON documents. We can satisfy the model with any implementation that satisfies the constraints of the algebra.
So you can use the framework to provide the implementation (which also happens to have all the hooks the framework needs); the behavior just interacts with the interface it defined itself.
In a strongly typed implementation, this can get really twisty. In Java, for instance, if you want the strong type checks you need to be comfortable with the magic of generics and type erasure.

The real answer to this is that DDD is overrated. It is not true that you have to have one model to rule them all. You may have different views on the state of your world, depending on your current needs. One part of the application has one view, another part - completely different view.
To put it another way, your model is not "what is", but "what happened so far". The actual data model of your application is the event stream itself. Everything else you derive from there.

Related

Can I say Axon Commands and Events are considered as anemic models?

My question here is quite straight as mentioned in the subject.
However, please allow me to give some brief explanation here about my innocent thoughts.
I've been using Axon for approximately 10 months now. I used to design my project structure based on the Hexagonal architecture with two top level packages respectively for domain and infrastructure.
Furthermore, domain package will contain different domain objects (as explained in the DDD concept) such as follow:
Aggregate (this will be an Axon aggregate class).
Repository (in my case, this will be a Spring Data Repository interface).
Entity (in my case, this contains any lookup entity that i used for set-based consistency validation as written here).
Service Port (collection of Input and Ouput port interfaces).
Commands (representing Axon Command object).
As for Events, I used to put them on a different module that I compiled as a jar file, so I can share it to other developers whom going to use the same event in their project.
I've noticed recently that all of my commands and events were basically anemic models (an anti pattern that we should avoid).
Is there any good practice on this ? Or, Is it something that intentionally used by design ?
I've been thinking to put my Command classes within my Aggregate class (as an inner classes). At least by using this approach I won't end-up with having so many anemic models scattered outside. Any thoughts ?
Commands are designed to be behavior and input structures mirroring the external world. They don't necessarily mirror an aggregate's structure.
They are not even connected clearly to one single aggregate, at times. Enclosing them within aggregates can be a code smell because you are then thinking in terms of resources and UI organization, instead of transaction boundaries and entity groups.
You are also violating the open-closed principle. Changes in volatile layers like user interface and request structures will make you edit the Aggregate class, and that is not good design.
On a more general note...
At times, this debate of anemic vs. non-anemic (or dry vs. non-dry) can push you in the direction of premature - and incorrect - optimization. Try avoiding this trap because you will end up optimising at the code level, but your domain will suffer.
DDD and CQRS guidelines align with principles that help you keep complexity at bay over the long term. Things kept distinct and separate help you achieve this.
First of all, in DDD, your domain had to be free of any frameworks, just use pure language library.
Then, mixing Commands and Aggregates cannot be a good solution. I think Commands belongs to Port while Aggregates belongs to the Hexagone.
Finally, DDD highlights the discovery of the domain thanks to the experts. Did you do that ? If not, if you're only using the Tacticts pattern, you'll miss one of the most important part of DDD.

How to Implement DDD repository pattern using raw JDBC or Mybatis?

let's say I have a complex aggregate root (AR)
in a user transaction, I multiple this AR:
ar.doSomeThing1();
ar.doSomething2();
ar.doSomething3();
ar.doSomething4();
then I use a repository to persistent all the change
arRepo.update(ar)
My question is How to Implement arRepo.update use row JDBC or Mybatis?
the main difficulty is :
arRepo does not know what changed, the only way is to update all the ar data in the database.
The main principle is that your DDD core should know nothing about JDBC, TCP or ORM. Everything it knows should be expressed in terms of a Ubiquitous Language.
But that doesn't mean it shouldn't know what changed. You may use sort of event sourcing and save events under AR from which necessary updates could be derived.
Maybe that gets not very object-oriented, but you may give it a try. Effectively, AR can be represented as a decision maker, who gets requests for changing its state, decides whether to accept these requests or reject, and then stores a list of state-changing events.
You then need to reduce this event list to a read model somewhere, but that's not the responsibility of AR, if you use this approach.
When I mention decision making, I mean a pure function that doesn't go to a disk or a network for data. It means, that all necessary data should be gathered prior to decision making and persisted afterwards. That goes to application layer.
And this application layer is who interacts with repositories or network adapters. It may also handle transactions and so on. Next, calculating an SQL UPDATE query is an implementation detail of a repository. But as long as a state changes are expressed in terms of ubiquitous language, it can well be known to aggregates and domain core.

DDD - how to rehydrate

Question: what is the best, efficient and future proof way to
rehydrate an aggregate from a repository? What are the pro's and con's of the provided ways and are my perceptions correct?
Let's say we have an Aggregate Root with private setters but public getters for accessing state
Behaviour is done through methods on the aggregate root.
A repository is instructed to load an aggregate.
At the moment I see a couple of possible ways to achieve this:
set the state through reflection (manual or automatic eg.
Automapper)
make constructors that accept properties so state is set
load the aggregate with a state object
1) Jimmy Bogard alludes that his tool Automapper isn't meant for two-way mapping. But some people argue that we have to be pragmatic, use tools in a way it helps you.
For me, I don't like a full rehydration through reflection. Maybe Automapper ceise to exist or aggregate roots are bent in such a way the mapping can be done (see some comments of Vaughn on his article).
2) creating constructors for rehydration, with a couple of parameters so the state of the aggregate is rehydrated in a correct way.
These couple of parameters can expand (= new constructors) or the definition can change. I like this approach, except the part of having a bunch of parameters.
3) the state is a property of the aggregate root. The state is encapsulated in a new object and this object is build by the repository and is then given to the aggregate root for proper init.
Some people argue that building this state object is more work (new class, exposure of state properties on entity and aggregate root to enforce business rules), but it provides a clean way to initiliaze the state.
Say that we need event sourcing, does the loading of a state resemble in loading events? And does the state object provide a way of handling events? Is it more future proof?
I would argue that trying to future-proof too much represents a trap that many people fall into that adds undue complexity to a codebase. There is a fine balancing act between sound architectural decisions and over-architecting a solution to problem that is not guaranteed to exist.
That being said, I fully agree with what Jimmy says, in regards to AutoMapper not being intended for two-way mapping. Your domain represents the "truth" in your application, and should not be directly mutable. I have worked on projects with two-way mappings, and while they do work, there is a tendency to start treating the domain objects as nothing more than DTOs. It becomes painful when you start having read-only properties, having to reflect to do your setting - tooling or not. From a DDD perspective, we should not be allowing for outside influences to simply say what a property value should be, because it will lead to an anemic domain model over time, most likely.
Internal states do work well, but they are at the cost of additional overhead and complexity. There is a legitimate trade-off, as you mention, in that you are adding a fair amount of work. However, you can use that opportunity to allow the aggregate to validate the state against the self-contained business rules within the aggregate, prior to allowing the state to be set. That addresses the largest concern that I have with two-way mapping. You can at least enforce that a state object contains valid data and then only construct the aggregate if it is valid. It is more testable, as well. The largest problem that I have seen with this approach is that the skill level of your team will have a direct bearing on the success of this being utilized correctly. It could be argued that the complexity does not add enough value to implement domain-wide, as you will likely have aggregates that have different levels of churn. A couple of projects that I have been involved in have used this approach, and I found little advantage over straight constructor usage.
Normally, I use constructors for rehydration in most cases. It walks the line between not being overly-complex, plus it leaves responsibility for the aggregate to allow or disallow the construction of the object - again, allowing for the domain to be in control of whether the hydration attempt would result in a valid object. A good compromise to constructor bloat is the use a mutable DTO as a parameter for the constructor, essentially acting as a data structure to maintain a consistent constructor signature over time. In that essence, it is also somewhat future-proof. It takes the most attractive perk of the state object approach, which is the clean signatures, but removes the additional layer of an internal abstraction.
You mention event sourcing as a possibility down the road. State loading is not very similar to what you would be doing, at all (in my opinion). With a state object, you are snapshotting the state of the aggregate at a given point in time. With event sourcing, you will be replaying events, each of which represents the data required to mutate the state, as opposed to the state, itself. As such, your constructor will likely be a collection of events, representing a chain of deltas to mutate the state repeatedly, until it reaches the current state. When you want to hydrate your aggregate, you will supply it with the events that are related to that aggregate, and it will replay them to get to the current state. This is one of the true strengths of event sourcing, as well. You are forcing the hydration of your domain objects to go through the business logic required to create them, each time. Given a list of events, the aggregate will enforce that each state change is valid by applying the event in a consistent fashion, whether the event is being applied in real-time, or replayed to get to the current state.
Back to the future-proof aspect, as it relates to event sourcing, there is a conscious effort required when events require change. Since you have to replay an event to get to the current state, you will very likely have to deprecate events and bring up new events to transition to as your business logic changes. You may (read as "likely will") find yourself versioning events. Not only does your aggregate need to understand current state change requirements, but it also needs to understand previous state change requirements. So, if you change an event handler, you will have to ensure that it will be valid for existing events, as well. When you are adding additional data to an event, it is usually not too involved. But when you start removing data from an event signature, you instantly make that event at risk for being incompatible with earlier structures. Likewise, even changing the names of the data structures inside of an event can cause backwards compatibility issues. If you start event sourcing, you do not need to worry as much about future-proofing as you do backwards compatibility. Event sourcing is great, but be prepared for additional complexity.

How to model transient state in DDD?

I am just getting my feet wet with my first Domain-driven Design project. The project's domain model involves a bounded context that deals with collision detection of moving geometries located in a three-dimensional scene.
A central part of the business logic would be the collision detection algorithm aka the CollisionDetector. The algorithm must be configured with some parameters that influence its behaviour and performance. So it has some state attached making me think of it as an entity or rather an aggregate in the first place. Note that there is no requirement to persist this entity to the DB - all its parameter values are transient. Also note that there is only a single CollisionDetector instance present in the domain, so implementing an in-memory repository giving access to that single aggregate seems a bit overdone to me.
Summing things up we have a stateful, transient entity with a singleton nature.
So here is my question: While "normal" aggregates in DDD should always be accessed via repositories, how should I deal with such a unique entity instance?
Is it advisable to use (evil) Singleton pattern here?
Should I rather register that entity with my IOC?
Should I implement an in-memory repository to just hold that single instance?
Is it even reasonable to model it as an entity at all? (It doesn't need identity for it's unique.)
Should I refactor to make it a (stateful!) domain service instead?
Is it maybe a design smell for the domain model to have several aggregates of this type?
I've heard about Sagas. Could they be the solution to my problem?
Please let me now if you need more context to help me with this issue.
P.S. And excuse my broken english. I'm not a native speaker.
Edit:
I feel I should give some further detail on CollisionDetector class and the state attached to it.
Maybe calling it transient was misleading. My intention was to point out that CollisionDetector will never be persisted to a storage. Its entire life is spent in active memory. Creation, modification and deletion are all part of its life cycle, persistence is not.
Another important quality of CollisionDetector is what I refer to as its singleton nature meaning that CollisionDetector is instanciated only once (but not necessarily using the GoF Singleton pattern). I am not sure whether the concept of identity is applicable to a singleton instance (at least there is no need for identification as there is just one), which is the only thing that keeps me from making CollisionDetector an entity/aggregate.
So let me shed some light on CollisionDetector's state as requested by #plalx, #guillaume31 and #arootbeer.
As mentioned already, there is a simple set of scalar parameter values used to tweak the algorithm to be either more accurate or faster. These parameters can be adjusted by the user at any time to fit his needs.
The CollisionDetector keeps track of the geometries and their pose inside the scene. This is achieved via Domain Events: When one of the geometries changes its pose an event handler will automatically trigger a collision test. Likewise newly detected collisions are published by the CollisionDetector via Domain Events as well. Note that not all geometries are considered to be collision candidates, the user may exclude some of them from the test. Hence the CollisionDetector holds a blacklist of geometry ids (beeing part of its state).
In order to detect collisions in realtime, the algorithm requires a preprocessing which is done in a separate initialization routine of CollisionDetector. Whenever a geometry is added to or removed from the scene, the preprocessing becomes stale and needs to be refreshed. The CollisionDetector is aware of that i.e. it knows whether a re-initialization is required or not.
Hope this helps!
Rethinking my question I must admit that it's merely academic. A pragmatic solution could be to make CollisionDetector an aggregate and just register it with the IoC container. What do you think?
The algorithm must be configured with some parameters that influence its behaviour and performance. So it has some state attached making me think of it as an entity or rather an aggregate in the first place. (emphasis mine)
I don't consider the configuration of the CollisionDetector to be its state. It is only configuration and cannot change once the CollisionDetector is instantiated, so it is something much simpler than mutable state that you typically find in entities.
As a consequence, I clearly consider the CollisionDetector a domain service. This means you should handle it as follows:
Register the CollisionDetector service in IoC. The configuration of the CollisionDetector is probably considered domain logic, so it could make sense to instantiate the CollisionDetector in a CollisionDetectorFactory. If that's the approach you take, register the factory in IoC instead. In any case, make sure the clients of the CollisionDetector don't have to know about its configuration.
By the way, don't use singletons (i.e. the GoF singleton pattern) when you work with IoC. You can always register a service as single instance, which has the same effect as the singleton pattern, but avoids its problems.

How to be with huge Domain classes in DDD?

When you are developing an architecture in OO/DDD style and modeling some domain entity e.g. Order entity you are putting whole logic related to order into Order entity.
But when the application becomes more complicated, Order entity collects more and more logic and this class becomes really huge.
Comparing with anemic model, yes its obviously an anti-pattern, but all that huge logic is separated in different services.
Is it ok to deal with huge domain entities or i understand something wrong?
When you are trying to create rich domain models, focus entities on identity and lifecyle, and thus try to avoid them becoming bloated with either properties or behavior.
Domain services potentially are a place to put behavior, but I tend to see a lot of domain service methods with behavior that would be better assigned to value objects, so I wouldn't start refactoring by moving the behavior to domain services. Domain services tend to work best as straightforward facades/adaptors in front of connections to things outside of the current domain model (i.e. masking infrastructure concerns).
You can also put behavior in Application services, but ask yourself whether that behavior belongs outside of the domain model or not. As a general rule, try to focus application services more on orchestration-style tasks that cross entities, domain services, repositories.
When you encounter a bloated entity then the first thing to do is look for sets of cohesive set of entity properties and related behavior, and make these implicit concepts explicit by extracting them into value objects. The entity can then delegate its behavior to these value objects.
Since we all tend to be more comfortable with entities, try to be more biased towards value objects so that you get the benefits of immutability, encapsulation and composability that value objects provide - moving you towards a more supple design.
Value objects enable you to incorporate a more functional style (eg. side-effect-free functions) into your domain model and thus free up your entities from having to deal with the complexity of adding complicated behavior to the burden of managing identity and lifecycle. See the pattern summaries for entities and value objects in Eric Evan's http://domainlanguage.com/ddd/patterns/ and the Blue Book for more details.
When you are developing an architecture in OO/DDD style and modeling
some domain entity e.g. Order entity you are putting whole logic
related to order into Order entity. But when the application becomes
more complicated, Order entity collects more and more logic and this
class becomes really huge.
Classes that have a tendency to become huge, are often the classes with overlapping responsibilities. Order is a typical example of a class that could have multiple responsibilities and that could play different roles in your application.
Given the context the Order appears in, it might be an Entity with mutable state (i.e. if you're managing Order's commercial condition, during a negotiation phase) but if you're application is managing logistics, an Order might play a different role: and an immutable Value Object might be the best implementation in the logistic context.
Comparing with anemic model, yes its
obviously an anti-pattern, but all that huge logic is separated in
different services.
...and separation is a good thing. :-)
I have got a feeling that the original model is probably data-centric and data serving different purposes (order creation, payment, order fulfillment, order delivery) is piled up in the same container (the Order class). Can't really say it from here, but it's a very frequent pattern. Not all of this data is useful for the same purpose at the same time.
Often, a bloated class like the one you're describing is a smell of a missing separation between Bounded Contexts, and/or an incomplete Aggregate separation within the same bounded context. I'd have a look to:
things that change together;
things that change for the same reason;
information needed to fulfill behavior;
and try to re-define aggregate boundaries accordingly. And also to:
different purposes for the application;
different stakeholders;
different implicit models/languages;
when it comes to discover the involved contexts.
In a large application you might have more than one model, thus leading to more than a single representation of a single domain concept, at least for concepts that are playing many roles.
This is complementary to Paul's approach.
It's fine to use services in DDD. You will commonly see services at the Domain, Application or Infrastructure layers.
Eric uses these guidelines in his book for spotting when to use services:
The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT.
The interface is defined in terms of other elements in the domain model
The operation is stateless

Resources