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
typeis somehow a constant withidentifierthen 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With