How to update shared information between 2 representations of the same entity in different contexts? - entity

This question is related, but more specific than this question.
I'm going to use a simple example here. Say we have a User entity in one context and a Customer entity in another context. These are 2 different representations of the same entity.
Let's say the User and Customer both have an email address, but the email address is always changed via the bounded context that the User belongs to. So the user context is the source of truth for the email address. So ideally I would like the email address in the Customer context to be immutable from the point of view of the customer context.
So when the email address is changed in the user context, an EmailAddressChanged event is emitted. This is fine; I subscribe to the event in the Customer context. However, I now need to handle this event by mutating the Customer email address. So I need some sort of command method to make this change.
How can I ensure that the command method is not used, other than when handling the event from the User context?
If I allow mutation in both contexts then they both become sources of truth and I need double the number of events and handlers to ensure that the information remains consistent in both contexts

Maybe there is a hidden customer/supplier relationship between these bounded contexts? If User bc is the source of truth for Customer bc, then User bc might expose an API to be accessed by downstream contexts (Customer, maybe something more?). In your question you said only the email address should be "immutable" and dependent on User context - however, I think it might a hint that entire Customer context is a consumer/customer of User context and should use its public API (which should not expose internal user domain model directly - some facade classes are required to hide the details).
If that's not the case, and there is no such relationship between the contexts - you can use a specialized component in your Customer bc to make changes to the database, without directly invoking domain methods. Then, the repository can be used to query customers and recreate them with updated email address. My point is - if you want customer bc to apply EmailAddressChanged events, you obviously need something to alter the database, but you don't need to do that via domain methods. The component applying EmailAddressChanged events would be part of the infrastructure layer of Customer context. If you use this solution, then there is no risk of modifying customers via business case scenarios.
Btw, isn't your Customer in fact a specialized read model of User context?

Related

DDD - can I use value objects as models helpers

I have an aggregate root called User.
Here's an example of how it's modelised:
User: {
id: string
username: string,
email: string,
auth: LocalAuth {
password: string
}
}
In my application, I have an API route -
POST /users/id/password - that allow users to change their password.
In order to change their password, we must ensure that users enters their old password. The request model should look like this:
{
oldPassword: string
newPassword: string
newPasswordRepeating: string // in case of user errors
}
The controller that handle this request should do the following:
Check if the oldPassword is equal to the current one
Check if the newPassword is valid
Update the user data
Return the updated user data
In order to handle such business logic, I could create a VO model named PasswordUpdate (idk..). This VO could encapsulate the validation logic in its own model.
Does this kind of implementation faithfully follows the DDD rules?
Because in my case, this VO is never contained in an Aggregate Root and is not stored. The purpose is only to modelise a password update with a domain model.
Does this kind of implementation faithfully follows the DDD rules?
Very short answer: go right ahead.
Short answer: the DDD police are not going to come after you anyway, so don't over think it.
Broad answer: I find that the description of Value Objects by Evans is something of a muddle, polluted by the fact that he was drawing from experience in Java.
But if you look really carefully, what's going on is that Evans is proposing the creation of a domain specific language that you can use to describe the behaviors of the model. Value objects are doing a few things: they are giving you domain specific types (so that the type system can assist, as it it able, in restricting the frequency of certain kinds of errors), they are giving you domain specific semantics (rather than insisting that all domain behaviors are described via operations on domain agnostic primitives), and they are providing an isolation layer between the domain behavior and the in memory representations of domain state.
The value of this is not restricted to the "domain model"; you should feel free to apply this abstraction everywhere it makes sense to do so.
BUT... there is a particular trap in the case that you describe that you should be aware of.
The domain model is something that you are supposed to able to change aggressively to meet the needs of the business, which of course can include changing the implementation of the value objects.
Messages, however, should be changed conservatively. Messages are part of the API. If we want to be able to release compatible clients and servers using a different cadence for each, then we need the interface between them to be stable. The message shouldn't be carrying domain rules with it (those belong in the model), it's just a representation of state.
"Validation" usually happens when we take the message (part of the api) and translate it into values understood by the model.

Avoiding abstract classes and inheritance

consider I am having an Event with Invitations (each "invited person" represents an Invitation, so multiple Invitations are out for a single Event):
[«aggregate root»;Invitation]<>1..*-[«value object»;EventIdentifier]
[«value object»;EventIdentifier]-<>[«aggregate root»;Event]
[«value object»;Invitee|emailAddress;facebookIdentifier]-<>[«aggregate root»;Invitation]
The Invitee, however, can bei either an Email Address or a facebookIdentifier, that's the nature of the business logic.
Usually I would have made an AbstractInvitee with FacebookInvitee and EmailInvitee, and created an association to the abstract, but that's evil as I know now.
Should I, instead, have actually FacebookInvitee and EmailInvitee and the Invitation has each a facebookInvitee and an emailInvitee property; and a Service or so would merge them together, if necessary?
Thanks for your advice!
Edit
I just came to the following idea which looks rather neat,
[«value object»;Invitee|type;identifier]-<>[«aggregate root»;Invitation]
The type is somehow a constant with FACEBOOK and EMAIL, and the identifier then is the FB UID or the email address respectively.
Usually I would have made an AbstractInvitee with FacebookInvitee and
EmailInvitee, and created an association to the abstract, but that's
evil as I know now.
Inheritance is not that evil.
If your classes FacebookInvitee and EmailInvitee have the same interface I see no reason to avoid inheritance. Inheritance adds complexity if interfaces are different and casting to concrete types is needed.
The type is somehow a constant with FACEBOOK and EMAIL, and the
identifier then is the FB UID or the email address respectively.
Your example is very similar to Replace Subclass with Fields refactoring. Anyway it will be needed to write if-else code-block to check invitee type and use its identifier for sending an invitation somewhere. Who should be responsible for it? In your solution Invitee is simply a DTO without behaviour. If Invitee has behaviour and can Send() an invitation itself then I would use inheritance and implement Send() for every concrete class (e.g. FacebookInvitee, EmailInvitee).
I'd still keep an abstract Invitee value object with 2 derivatives EmailInvitee and FacebookInvitee.
Each type of Invitee can raise its own flavor of WasNotified Domain Event which is then captured by an Infrastructure layer notification service that knows how to handle it.
I like your idea in edit.
You could place a NotificationService in the domain layer and add adapters in the infrastructure layer(FacebookNotificationService / EmailNotificationService).
And a NotificationDispatcher(it is also an adapter but aggregates other adapters) to dispatch notification(by invitee type) to the corresponding adapter.

How do you represent domain object behaviors using methods when a domain object is acted upon and not the actor?

In Domain Driven Design, there is an emphasis of placing behaviors where they correctly belong. I'm not always sure what exactly constitutes "correct," though.
Consider this scenario: "The client withdraws an amount of money from a bank account."
Grammatically, we have that:
'client' is a subject
'withdraw' is a verb
'amount' is a direct object
'account' is an affected prepositional object
Classically, the client would execute this: account.withdraw(amount).
This could be read as: "The client commands a bank account to withdraw an amount of money." However, this does not grammatically correspond to the original scenario, since 'bank account' is now the direct object and an infinitive removes 'withdraw' and 'amount' from the main clause so that the primary idea conveyed is that 'client commands account'.
To adhere to DDD, we should regard this code as precisely describing the original scenario. This implies that the 'withdraw' method does not model a behavior performed by the account (the account is not a subject), but rather it models a behavior that indirectly affects it (the account is a prepositional object) and could very well be renamed 'wasWithdrawnFrom'. Moreover, the method argument represents something being affected by the client as opposed to by the object (it is a direct object for a client subject, not an object subject).
If we extrapolate from this example, we can see that methods may represent behaviors that affect the object (object is not the subject) and method arguments may represent direct objects of a client subject.
However, whether or not methods should represent behaviors performed by objects is unclear.
So my question is: How should we use methods to model object behavior?
1) Methods should strictly represent behaviors that affect the object. (The object cannot act as a subject, only a grammatical direct/indirect/prepositional object)
2) Methods may represent both behaviors that affect the object as well as behaviors performed by the object. (The object may act as a subject or a grammatical direct/indirect object)
You seems to be stuck in a theoretical thesis. I'm not sure you can apply a theory that works for every scenario/project. Behaviors usually appears when you start bombarding your Model with Use Cases. I try to let the cases dictate behaviors.
To follow your example:
Actor Customer want to withdraw money from Account. The way to do it is like you do Account.Withdraw(Money amount)
But your question "How should we use methods to model object behavior?" is a common DDD question. How to enrich your model with behavior? My best hints is to find your Value Objects. Value objects usually comes with behavior.
In example Account is and Entity (Aggregate root probably). Money (Value object with Currency and Amount) should be withdrawn from an Account. That should be Account Single Responsible (Principle) to control that Account balance and all access to it.
Regarding your (2) question in the end. Methods are absolutely used for change the objects inner state. But when it comes to behaviors performed by the entity/value object like
Customer.Order(newOrder) or advert.Apply(candidateCV) we can make entities communicate with each other. We can also create chained behaviors through Domain Events which can help us not to leak to much business logic to our application services. See Udi Dahan's blog for that or my blog article regarding Anemic Domain model http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I Hope you got some ideas. It's difficult to give concrete hints when we are so abstract here.
/Best regards Magnus
I find that scenario too simple to be real, hence too simplistic to model too. I would reformulate the
"The client withdraws an amount of money from a bank account."
to something like
"The client submits withdrawal request of value xxx $ from his account" (when I go to my bank I have to fill out a form in order to withdraw money where I state amount, the account number, date and my signature)
There one can spot a request (command) to a service (withdrawal service) of an client (client identified by ID) from his account (account identified by ID) and the money value (money as value object).
I don't care much about the grammar, as English is my second language so when trying to understand the Domain, I try to understand how the business sees the concepts (Account) and workflows (withdraw an amount) and not to do grammar analysis.
The point of DDD is to model things like they are in the business, so behaviour shows up according to Domain understanding.
in this scenario, for me it's clear that we're working within the Account Operations Bounded Context and at least the Account aggregate root is involved. Of course, in banking terms, probably (I'm guessing here) there will not be a withdrawl but an operation to increase the Debit/Credit part of an account, so most likely the account will register that a debit/credit operation has happened. And a Domain Event is born and published. Then let the domain expert tell you what will happen next.
"The client deletes an order" => order.delete
Probably the order is never deleted, but its status will changed to 'canceled' or similar. However for that case when an order really should be deleted, the order doesn't delete itself, the Orders repository deletes that order.

REST API Design - handling resource subtypes

In the API I'm putting together, I perform an Action over a set of entities. The issue I'm having is how to allow the action to vary depending on the client's preferences and supported methods.
Some of the action types will need the client to provide additional options: for instance, one of the actions will result in an email being sent, so the client needs to provide the body, recipients and so on. The server may know about more action types than the client does. For instance, a new sending method could be added, but an old client isn't going to know how to set up the options for it. As well as that, there are action types that require no options from the client, and hence all clients can use that as soon as the server is enabled for it.
As well as varying the action types based on those supported by the client/server, the entities selected also have an effect -- some entities are not valid for some action types.
At the end of this negotiation, the client (ultimately the end user) is free to choose from any of the 'no-option' action types applicable to these entities, or any of the 'need-options' action types applicable to these entities, and supported by both the client and the server.
Actions are triggered by setting a status field to committed or similar.
My thoughts so far are to provide a generic DoAction resource, with a sub-collection of the entities. A property on this resource lets you specify the 'ActionType'. There is then another sub-resource called ActionOptions and it's this where you either set the options for the particular type you're using, or leave it empty for 'no-option' types.
The issue I'm having is to decide if this is the best approach, or if something involving content types would be better, and also how to negotiate the list of available action types for the client, including the no-option types which the client can support even if it doesn't explicitly know about it.
I decided to add two read-only collections to the DoAction resource, one listing the no-option action types, and one listing the need-options types (plus could optionally include schema-like info there). These collections are based on the entities included.
The client sets their action type and the options, which is a dynamic key/value store. When the status is changed to committed, that's an opportunity to validate the resource prior to performing the action.

Validation approaches in ddd

I have a question on validation approaches in ddd. I've read quite controversial opinions on that. Some say that this should live out of entity, others say that this should be placed in entity. I'm trying to find an approach that I could follow.
As an example, suppose I have the User entity with email and password. User has a method Register(email, password). Where should the email and password validation be placed? My personal opinion is that it should be inside the Register() method. But such approach might lead to messing User class with validation stuff. One approach might be to extract the email and password rules in separate policy objects and still invoke them from Register() method.
What is your opinion on validation approaches in DDD?
First off, I think validation is somewhat of a slippery subject due in part to the various contexts within which it needs to be considered. Ultimately, there will be validation rules executed at various application layers. At the very least, there should be standard guards in domain objects. These are just regular pre-condition and argument checks that should be part of any well designed object and fits with your opinion for the Register method. As stated by lazyberezovsky, this is to prevent the objects from getting into an invalid state. I side with the always-valid school of though on this. I think if there is a need to persist entities in an invalid state, a new entities should be created for this purpose.
One issue with this approach alone however is that there is often a need to export these validation rules to other layers, such as to a presentation layer. Moreover, in the presentation layer, the rules need to be formatted differently. They need to be presented all at once and potentially translated into another language, such as JavaScript for immediate client-side feedback. It can be difficult or impractical to attempt to extract validation rules from exceptions raised by a class. Alternatively, the validation rules can be re-created at the presentation layer. This is much simpler and although potentially violating DRY it allows for the rules to be context dependent. A specific workflow may require for different validation rules than the ones enforced by the entity itself.
The other issue with the described approach is that there may be validation rules which exist outside of the scope of an entity, and these rules must be consolidated together with the other rules. For example, for user registration, another rule is to ensure that the email address is unique. The application service hosting the applicable use case would usually enforce this rule. However, it must also be capable of exporting this rule to other layers, such as presentation.
Overall, I try to place as many constraint checks into the entities themselves because I think entities should be always-valid. Sometimes it is possible to design the rule framework such that it can be used to both raise exceptions and be exportable to outer layers. Other times it is easier to simply replicate the rules across layers.
Actually validity of user is context dependent. User can be valid (name and email are valid), but registration operation can be impossible to perform. Why? Because there can be already existing user with same name. So, user which looks like valid in some context, can be invalid in registration context.
So I'd moved part of validation into entities or value objects (e.g. Mail object) to avoid obviously invalid states of entities (e.g. user with null name). But context-dependent validation should exist in that context. So, if I'm registering user:
Mail mail = new Mail(blahblahblah); // validates if blah is valid email
User user = new User(name, mail); // validates if name is valid and mail not null
// check if there already exist user with such name or email
repository.Add(user);
Also I think that method Register should be method of some domain service (like MembershipService), because it definitely should use some repository.
As an example, suppose I have the User entity with email and password. User has a method Register(email, password). Where should the email and password validation be placed?
If you are following DDD, email address and username are key concepts in your domain - so they should be represented as entities. In that case, the validation for an email address lives in the EmailAddress entity, and the validation for username should be placed in the Username entity.
pseudocode example:
class EmailAddress
{
Constructor(string email)
{
if (email.DoesNotMatchRegex("\w+#\w+.\w{2,3}"))
throw error "email address is not valid"
}
}
class Username
{
Constructor(string username)
{
if (username.length < 6)
throw error "username must be at least 6 characters in length"
}
}
class User
{
Register(Username username, EmailAddress email)
{
if (username == null)
throw error "user must have a username"
if (email == null)
throw new error "user must provide email address"
// At this point, we know for sure that the username and email address are valid...
}
}
First of all i would separate between two things: Validation and Business Rules where the latter normally goes into a service or an entity method. For validation such as valid e-mail address or valid passwords i usually stick them onto the entity that owns them so i can move them around with the entity if i ported my application to a different platform. Now for your register method example i can't see why would this method be called in the first place if the object was in an invalid state, and if it will be called i will make it a step in another method like SignUp that might do something like this: if (isValid()) register(username, password).