I have an aggregate that includes the entities A, AbstractElement, X, Y and Z. The root entity is A that also has a list of AbstractElement. Entities X,Y and Z inherit from AbstractElement. I need the possibility to add instances of X, Y and Z to an instance of A. One approach is to use one method for each type, i.e. addX, addY and addZ. These methods would take as arguments the values required to create instances of X, Y and Z. But, each time I add a new type that inherits from AbstractElement, I need to modify the entity A, so I think it's not the best solution.
Another approach is to use an abstract add method addAbstractElement for adding AbstractElement instances. But, in this case, the method would take as argument an instance of AbstractElement. Because this method would be called by entities located outside of the aggregate, following DDD rules/recommandations, are these external entities authorized to create instances of AbstractElement? I read in the Eric Evans book that external entities are not authorized to hold references of entities of an aggregate other than the root?
What is the best practice for this kind of problem?
Thanks
From Evan's book, page 139:
"if you needed to add elements inside a preexisting AGGREGATE, you might create a FACTORY METHOD on the root of the AGGREGATE"
Meaning, you should create a factory method on the root (A) which will get the AbstractElement's details. This method will create the AbstractElement (X/Y/Z) according to some decision parameter and will add it to its internal collection of AbstractElements. In the end this method return the id of the new element.
Best Regards,
Itzik Saban
A few comments. As the previous answerer said, it's a good practice to use a factory method. If you can avoid it, never create objects out of the blue. Usually, it's a pretty big smell and a missed chance to make more sense out of your domain.
I wrote a small example to illustrate this. Video is in this case the aggregate root. Inside the boundaries of the aggregate are the video object and its associated comments. Comments can be anonymous or can have been written by a known user (to simplify the example, I represented the user by a username but obviously, in a real application, you would have something like a UserId).
Here is the code:
public class Video {
private List<Comment> comments;
void addComment(final Comment.Builder builder) {
this.comments.add(builder.forVideo(this).build());
// ...
}
}
abstract public class Comment {
private String username;
private Video video;
public static public class Builder {
public Builder anonymous() {
this.username = null;
return this;
}
public Builder fromUser(final String username) {
this.username = username;
return this;
}
public Builder withMessage(final String message) {
this.message = message;
return this;
}
public Builder forVideo(final Video video) {
this.video = video;
return this;
}
public Comment build() {
if (username == null) {
return new AnonymousComment(message);
} else {
return new UserComment(username, message);
}
}
}
}
public class AnonymousComment extends Comment {
// ...
}
static public class UserComment extends Comment {
// ...
}
One thing to ponder on also is that aggregate boundaries contain objects and not classes. As such, it's highly possible that certain classes (mostly value objects but it can be the case of entities also) be represented in many aggregates.
Related
i'm stuck with this problem while designing aggregates in a DDD project.
Please consider the following scenario:
public abstract class BaseAppType{
public abstract int GetUserOwnerId();
public List<AppTypeHost> Hosts {get;set;} = new List<AppTypeHost>()
}
public class PersonalAppType:BaseAppType //this is an aggregate root
{
public int override GetUserOwnerId(){ return Hosts.Select(h=>h.UserId).Single(); }
}
public class TeamAppType:BaseAppType //this is another aggregate root
{
publi int TeamOwnerId {get;set;}
public int override GetUserOwnerId(){ //this is much harder becase i don't have the info in the object }
}
public class Team {
public List<TeamMember> TeamMembers = new List<TeamMember>();
}
public class TeamMember {
public int TeamId {get;set;}
public int UserId {get;set;}
public TeamMemberRole Role {get;set;} //this might be either Owner or Member
}
So basically i've two types of appointments that share common info, functionality and shape via a root class.
Now i've to implement GetUserOwnerId in the two derived class, which are two distinct aggregates root.
In the PersonalAppType it is kind of easy because the information of the userOwner is within one of the entity of the aggregate so i simply query the object in memory and return it.
In the TeamAppType it is more diffuclt because the information is in another aggregate root ( basically for my business rules, the owner of the TeamAppType is the Owner of the Team AggregateRoot).
Since Team is another AggregateRoot i could not load it into the TeamAppType aggregate and i pretty stuck...
I've tried:
the route of injecting a service in the TeamAppType
so that i can call it within the GetUserOwnerId but i don't like it because it feel "wrong" to inject a service within a domain constructor and it is kind of hard because when i retrieve the aggregate root from ef core, it doesn't inject the service ( because it uses the default construcor with 0 params )
I've also tried the route of doing it in a domain service, something like this:
public class AppTypeOwnerResolverService{
public int GetUserOwnerId (BaseAppType appType)
{
switch (appType.GetType())
{
case "PersonalAppType":
//retrieve owener of PersonalAppType
break
case "TeamAppType":
//retrieve owener of TeamAppType
break
}
}
}
but it feels off because it looks like the GetUserOwnerId should stay within the inherited class and this reduces the benefits of polymorfism.
Do you have any suggestion on how to approach this problem?
Thanks to everyone for the help.
Another option would be to have a Team aggregate emitting domain events, (i.e. TeamOwnerAssigned) and having a domain event handler that modifies the TeamAppType aggregate based on this event.
Creating instances
I am new to DDD and wondering if the Factory that creates the Entity is responsible for creating the Value Objects. Here is a small example of what I have until this moment:
class User extends Entity {
public name: UserName;
constructor (name: UserName) {
this.name = name;
}
}
class UserName extends ValueObject {
public userName: string;
}
class UserFactory {
public create(string name) {
return new User(
new UserName(name)
);
}
}
I think that way the components that create an user (UserEntity) just need to pass the string to the factory and thats all. But on the other side this code is not following the Single responsibility principle. Maybe it is better to just pass the UserName value object directly?
class UserFactory {
public create(UserName userName) {
return new User(
userName
);
}
}
Validation
The other concept that is still unclear to me is the validation. Talking about the validation when creating the object (UserEntity). Is the UserFactory responsible for it? For example:
class UserFactory {
public create(UserName userName, UserLastName userLastName) {
if (userName == userLastName)
// throw validation exception
return new User(
userName,
userLastName
);
}
}
Image I added lastName to the UserEntity as ValueObject. I know it is dummy to compare the both names but just to give an example.
So is it correct that way - to remove the responsibility from the UserEntity or the following snippet is better:
class User extends Entity {
public name: UserName;
public lastName: UserLastName;
constructor (name: UserName, lastName: UserLastName) {
if (name == lastName)
// throw validation exception
this.name = name;
this.lastName = lastName;
}
}
The most interesting thing to me is when there is a change in the constructor of the Entity (add more required parameters to the constructor). I am searching for the approach that is going to cause the smallest number of changes as possible - using Factory pattern of just the constructor of the Entity? What are the biggest advantages in using Factory over the simple way - constructor (if there are).
I think you might be complicating things. The factory pattern is not really part of DDD, but it's a design pattern to use when building an object is complex or you want to hide some of the attributes that the Entity needs to work (for example in UIs, the elements might need some access to the class that does the rendering). There's a lot more info if you go to duckduckgo and search for design factory pattern
The examples you showed don't really require a factory. If all the factory is doing is passing parameters to a constructor, it's not adding anything.
About validation, the idea is that a constructor should never return successfully if an object is not usable, so in your examples, the null validations should be in the constructor of the object if the parameter cannot be null.
About value objects, again, why do you need a Factory? What benefit does it bring? I honestly cannot think of one case where it makes sense to have a Factory class. Sometimes, to make code a bit cleaner, one might use a factory method. For example, in Java the class Optional can only be constructed by calling the static builder method Optional.of() (which by the way, does some extra validation that only applies to that method).
TL;DR: use a Factory class if it brings a benefit, otherwise just instantiate class directly.
An aggregate (Article) has an entity (SmsContent) with a property (enabled) that only can change if a condition on the aggregate is met.
e.g.
<?php
//Aggregate
class Article {
/** #var User */
protected $user;
/** #var SmsOutput */
protected sms;
...
public function enableSms() {
if($this->user->hasPermission('sms')) {
throw new PermissionDeniedException('sms');
}
$this->sms->enable();
retutn $this;
}
public function getSms() {
return $this->sms;
}
...
}
//Entity
class SmsOutput {
/** #var boolean */
protected enabled = false;
...
public function enable() {
$this->enable = true;
}
...
}
How should you get the SmsContent entity from the Article without being able to change the enabled property from outside the aggregate?
For example:
$article->getSms()->enable();
How is this handled in DDD?
You have multiple options, depending on the architecture.
1. Use CQRS
In CQRS the Write is separated from the Read. This means that you don't interrogate the Aggregate, ever. You don't have any getters, only command handlers. If you can't interrogate the Aggregate you can't access any nested entity either. If you need to get data you do it only from a projection/read model that are read-only by default.
2. Use a different interface for returned entities
In this case you return the entity but it is type-hinted as being a sub-set of the actual entity. In your case you could have something like this:
<?php
interface SmsOutput
{
//...
public function isEnabled(): bool;
//...
}
//Entity
class SmsOutputWritable implements SmsOutput
{
/** #var boolean */
private $enabled = false;
//...
public function enable()
{
$this->enabled = true;
}
public function isEnabled(): bool
{
return $this->enabled;
}
//...
}
//Aggregate
class Article
{
/** #var User */
private $user;
/** #var SmsOutputWritable */
private $sms;
//...
public function enableSms(): void //no return values, see CQS
{
if ($this->user->hasPermission('sms')) {
throw new PermissionDeniedException('sms');
}
$this->sms->enable();
}
public function getSms(): SmsOutput
{
return $this->sms;
}
//...
}
Although the caller gets a SmsOutputWritable it does not know about this.
P.S. Anyway, even if the caller knows (or casts) that the returned value is SmsOutputWritable and call SmsOutputWritable::enable() nothing really happens because the caller can't persist the changes to the repository, only entire aggregates can be persisted not individual nested entities. This is because aggregates and/or nested entities don't persist themselves, only an Application service can do this, using a repository.
How should you get the SmsContent entity from the Article without being able to change the enabled property from outside the aggregate?
Short answer: You don't. You get an immutable representation (ie: a value type) of the SmsContent.State from the Aggregate Root.
That's the approach taken by Evans in Domain Driven Design. There have been a couple of innovations that have gained traction since then.
One is the idea that a single entity can serve in multiple roles. Rather than having a single repository that serves many different use cases, you might have many repositories that handle specific cases. Here, that might look like a repository that returns the Aggregate Root when you want to be able to change something, and a different repository that returns a view/projection for use cases that only inspect the data.
This separation goes really well with ideas like lazy loading; if you aren't going to need some data for a particular use case, you interact with a repository that doesn't load it.
Udi Dahan's essay Better Domain-Driven Design Implementation provides a high level overview.
This looks a lot like the CQRS suggestion of Constantin. I mean, when you start using different repositories for reads and writes, then you're already with one feet in CQRS
It does, but there are a few intermediate steps along the way; CQS, responsibility driven design.
I'm trying to avoid ending up with an anaemic Domain Model, so I'm attempting to keep as much logic as possible within the domain model itself. I have a method called AddIngredient, which needs to add a new KeyedObject to my Recipe Aggregate.
As the Domain Models themselves are meant to be devoid of repositories, I'm getting the ingredient via a business rule class:
public class Recipe : AggregateObject
{
public void AddIngredient(int ingId, double quantity)
{
GetIngredientMessage message = new GetIngredientMessage();
message.IngredientId = ingId;
GetIngredient handler = ServiceLocator.Factory.Resolve<GetIngredient>();
Ingredient ingredient = handler.Execute(message);
Ingredients.Add(new OriginalIngredient()
{
Ingredient = ingredient,
Quantity = quantity
});
}
}
As you can see, I'm using a line the line ServiceLocator.Factory.Resolve<GetIngredient>(); to obtain my GetIngredient business rule class. GetIngredient is a simple command handler that looks like the following:
public class GetIngredient : ICommandHandler<Ingredient, GetIngredientMessage>
{
private readonly IIngredientRepository _ingredientRepository;
public GetIngredient(IIngredientRepository ingredientRepository)
{
_ingredientRepository = ingredientRepository;
}
}
I assign my IoC factory class to the ServiceLocator.Factory, so the Domain has the ability to use its own interfaces, without seeing the concrete class implementation:
ServiceLocator.Factory = new IoCFactory();
I'm pretty sure I'm doing something wrong as it all feels a little bit bodge-like.
Can anyone spot anything blatantly wrong?
Is there a more appropriate way to instantiate a business rule handler such as GetIngredient without a static reference to my IoC Factory?
I suggest you introduce another layer into the design -- the Application layer. This layer responsibility would be to translate commands (either explicitly encapsulated in command objects or passed implicitly as int ingId, double quantity) into domain model invocations (Recipe.AddIngredient).
By doing so you'll move the responsibility of finding an ingredient by its id to a layer above domain, where you can safely make use of repositories directly without introducing unwanted coupling. The transformed solution would look something like this:
public class ApplicationLayer
{
private readonly IRecipeRepository _recipeRepository;
private readonly IIngredientRepository _ingredientRepository;
/*
* This would be called by IoC container when resolving Application layer class.
* Repositories would be injected by interfacy so there would be no coupling to
* concrete classes.
*/
public ApplicationLayer(IRecipeRepository recipeRepository, IIngredientRepository ingredientRepository)
{
_recipeRepository = recipeRepository;
_ingredientRepository = ingredientRepository;
}
public void AddIngredient(int recipeId, int ingId, double quantity)
{
var recipe = _recipeRepository.FindById(recipeId);
var ingredient = _ingredientRepository.FindById(ingId);
recipe.AddIngredient(ingredient, quantity);
}
}
And the now simplified Recipe class would look something like this:
public class Recipe : AggregateObject
{
public void AddIngredient(Ingredient ingredient, double quantity)
{
Ingredients.Add(new OriginalIngredient()
{
Ingredient = ingredient,
Quantity = quantity
});
}
}
Hope that helps.
If you're in a team and a programmer gives you an interface with create, read, update and delete methods, how do you avoid type switching?
Quoting Clean Code A Handbook of Agile Software Craftsmanship:
public Money calculatePay(Employee e)
throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
There are several problems with this function. First, it’s large, and when new
employee types are added, it will grow. Second, it very clearly does more than one thing.
Third, it violates the Single Responsibility Principle7 (SRP) because there is more than one reason for it to change. Fourth, it violates the Open Closed Principle8 (OCP) because it must change whenever new types are added. But possibly the worst problem with this
function is that there are an unlimited number of other functions that will have the same
structure. For example we could have
isPayday(Employee e, Date date),
or
deliverPay(Employee e, Money pay),
or a host of others. All of which would have the same deleterious structure.
The book tells me to use the Factory Pattern, but in way that it makes me feel that I shouldn't really use it.
Quoting the book again:
The solution to this problem (see Listing 3-5) is to bury the switch statement in the
basement of an ABSTRACT FACTORY,9 and never let anyone see it.
Is the switch statement ugly?
In reality, the employee object should have its own calculate pay function that will give you the pay. This calculate pay function would change based on what type of employee it was.
That way it is up to the object to define the implementation, not the user of the object.
abstract class Employee
{
public abstract function calculatePay();
}
class HourlyEmployee extends Employee
{
public function calculatePay()
{
return $this->hour * $this->pay_rate;
}
}
class SalariedEmployee extends Employee
{
public function calculatePay()
{
return $this->monthly_pay_rate;
}
}
When you build the Factory, THEN you do the switch statement there, and only once, to build the employee.
Lets say Employee was in an array, and the type of employee was held in $array['Type']
public function buildEmployee($array)
{
switch($array['Type']){
case 'Hourly':
return new HourlyEmployee($array);
break;
case 'Salaried':
return new SalariedEmployee($array);
break;
}
Finally, to calculate the pay
$employee->calculatePay();
Now, there is no need for more than one switch statement to calculate the pay of the employee based on what type of employee they are. It is just a part of the employee object.
Disclaimer, I'm a minor, so I'm not completely positive on how some of these pays are calculated. But the base of the argument is still valid. The pay should be calculated in the object.
Disclaimer 2, This is PHP Code. But once again, the argument should be valid for any language.
You can totally remove the switch by using a Map of some kind to map the type of an employee to it's corresponding pay calculator. This depends on reflection and is possible in all languages I know.
Assuming the pay calculation is not a responsibility of an employee, we have an interface PayCalculation:
interface PayCalculation {
function calculatePay(Employee $employee);
}
There's an implementation for each category of employee:
class SalariedPayCalculator implements PayCalculation {
public function calculatePay(SalariedEmployee $employee) {
return $employee.getSalary();
}
}
class HourlyPayCalculator implements PayCalculation {
public function calculatePay(HourlyEmployee $employee) {
return $employee.getHourlyRate() * e.getHoursWorked();
}
}
class CommissionedPayCalculator implements PayCalculation {
public function calculatePay(CommissionedEmployee $employee) {
return $employee.getCommissionRate() * $employee.getUnits();
}
}
And the pay calculation would work something like this. Reflection becomes important for this to look at an object and determine it's class at run-time. With this, the switch loop can be eliminated.
public class EmployeePayCalculator implements PayCalculation {
private $map = array();
public function __construct() {
$this->map['SalariedEmployee'] = new SalariedPayCalculator();
$this->map['HourlyEmployee'] = new HourlyPayCalculator();
$this->map['CommissionedEmployee'] = new CommissionedPayCalculator();
}
public function calculatePay(Employee $employee) {
$employeeType = get_class($employee);
$calculator = $this->map[$employeeType];
return $calculator->calculatePay($employee);
}
}
Here we are initializing the map in the constructor, but it can easily be moved outside to an XML configuration file or some database:
<payCalculation>
<category>
<type>Hourly</type>
<payCalculator>HourlyPayCalculator</payCalculator>
</category>
<category>
<type>Salaried</type>
<payCalculator>SalariedPayCalculator</payCalculator>
</category>
...
</payCalculation>
I read it somewhere, that if you're using a switch, then it's suspect that there's too much variation. And when we have too much variation, we should try to encapsulate the variation behind an interface, thereby decoupling the dependencies between objects. Having said that, I think that you should try to create an SalaryType lightweight base class object that will encapsulate this type of logic. Then you make it a member of class Employee and rid yourself of the switch construct. Here's what I mean in a nutshell:
abstract class SalaryType
{
function calculatePay() {}
}
class CommissionedType extends SalaryType
{
function calculatePay() {}
}
class HourlyType extends SalaryType
{
function calculatePay() {}
}
class SalaryType extends SalaryType
{
function calculatePay() {}
}
class Employee
{
private $salaryType;
public function setType( SalaryType emp )
{
$this->salaryType = emp;
}
public function calculatePay()
{
$this->salaryType->calculatePay();
}
}
Btw, a lot of your example code does not seem very "PHP-ish". There are no return types in PHP nor is there really any type safety. Keep in mind also that PHP is not truly polymorphic, so some of the polymorphic behavior found in typical type-safe languages may not work as expected here.