I've got a User domain object class, and a UserDAO class. The User only cares about it's state, and UserDAO only about the data storage. From what I've read, they should not know nor care about each other.
I then wondered how I could use my User class to do things with UserDAO and vice versa. After some research I found out about Service classes, that they're supposed to couple a bunch of related classes together for interaction User and UserDAO in my case).
If DAOs aren't supposed to know nor care about domain objects why have I seen some DAOs that accept their corresponding domain object as an argument or even return it?
class UserDAO
{
//other logic
public function fetchById($id)
{
//user fetch logic
return new User(...);
}
public function persist(User $user)
{
//user persist logic
}
//other logic
}
What would be the correct way of handling this? With the above UserDAO is clearly aware of User.
There's a bit of a confusion here...
In DDD context the Reposity pattern fits better than DAO objects. You can check the difference between Repository and DAO here.
The repository do have knowledge about your domain objects, but your domain object do not know about repositories. The reason for this is separation of concerns and good layering.
Repositories is usually injected at some aplication level class. Example of aplication level classes are classes that process the user request like controllers(mvc contexts) or webservices.
Repositories can also be injected in Domain Service but Domain Services is normally used to resolve problems of significant business operation or for operations that do not belong to a unique entity in domain context.
Related
Good morning,
I've a model where a User AR has a specific UserRole (administrator, reseller or client). For that AR, there are some guards I would implement which are:
An administrator cannot have a manager other than himself
A reseller cannot have a manager other than an administrator
A client cannot have a manager other than a reseller or client (sub-account case)
Let's say that I want to register a new User. The flow would be as follows:
RegisterUser request handler -> RegisterUser Command -> RegisterUser command handler -> User->register(...) method ->UserWasRegistered Domain event
How and where I should implement the guards to validate my User AR exactly? Right now, I've something that look as follows:
namespace vendor\Domain\Model;
class User
{
public static function register(
UserId $userId,
User $manager,
UserName $name,
UserPassword $password,
UserEmail $email,
UserRole $role
): User
{
switch($role) {
case UserRole::ADMINISTRATOR():
if(!$userId->equals($manager->userId)) {
throw new \InvalidArgumentException('An administrator cannot have a manager other than himself');
}
break;
case UserRole::RESELLER():
if(!$manager->role->equals(UserRole::ADMINISTRATOR())) {
throw new \InvalidArgumentException('A reseller cannot have a manager other than an administrator');
}
break;
case UserRole::CLIENT():
// TODO: This is a bit more complicated as the outer client should have a reseller has manager
if(!$manager->role->equals(UserRole::RESELLER()) && !$manager->role->equals(UserRole::Client())) {
throw new \InvalidArgumentException('A client cannot have a manager other than a reseller or client');
}
}
$newUser = new static();
$newUser->recordThat(UserWasRegistered::withData($userId, $manager, $name, $password, $email, $role, UserStatus::REGISTERED()));
return $newUser;
}
}
As you can see here, guards are in the User AR, which I think is bad. I'm wondering if I should either put those guards in external validators or in the command handler. Another thing is that I should probably also access the read model to ensure uniqueness of user and existence of manager.
And the last thing is, I would prefer pass a UserId VO rather than a User AR for the manager property, hence my thinking that guards should not be put in the User AR.
Your advice would be much appreciated.
As you can see here, guards are in the model himself which I think is bad. I'm wondering if I should either put those guards in external validators or in the command handler.
With DDD, you strive to keep business logic within the domain layer and more specifically into the model (aggregates, entities and value objects) as much as possible to avoid ending up with an Anemic Domain Model. Some types of rules (e.g. access control, trivial data type validation, etc.) may not be considered business rules by nature and could therefore be delegated to the application layer, but the core domain rules should not leak outside the domain.
I would prefer pass a UserId value object rather than a User aggregat for the manager property
Aggregates should aim at relying on data within their boundary to enforce rules as it's the only way to ensure strong consistency. It is important to realize that any checks based off data external to the aggregate could have been made on stale data and therefore the rule might still get violated through concurrency. The rule can then only be made eventually consistent by detecting violations after they occurred and act accordingly. That doesn't mean the checks are worthless though, as it will still prevent most violations to occur in low-contention scenarios.
When it comes to providing external information to aggregates, there are two main strategies:
Lookup the data before calling upon the domain (e.g. in the application service)
Example (pseudo-code):
Application {
register(userId, managerId, ...) {
managerUser = userRepository.userOfId(userId);
//Manager is a value object
manager = new Manager(managerUser.id(), managerUser.role());
registeredUser = User.register(userId, manager, ...);
...
}
}
When to use? This is the most standard approach and the "purest" (aggregates never perform indirect IO). I would always consider this strategy first.
What to watch for? As in your own code sample, it may be tempting to pass an AR into another's method, but I would try to avoid it to prevent unexpected mutations of the passed AR instance and also to avoid creating dependencies on a larger-than-needed contract.
Pass a domain service to the domain which it can use to lookup data on it's own.
Example (pseudo-code):
interface RoleLookupService {
bool userInRole(userId, role);
}
Application {
register(userId, managerId, ...) {
var registeredUser = User.register(userId, managerId, roleLookupService, ...);
...
}
}
When to use? I would consider this approach when the lookup logic itself is complex enough to care about encapsulating it in the domain rather than leaking it into the application layer. However, if you want to maintain aggregates "purity" you could also extract the whole creation process in a factory (domain service) which the application layer would rely upon.
What to watch for? You should always keep the Interface Segregation Principle in mind here and avoid passing large contracts such as IUserRepository when the only thing looked up is whether or not a user has a role. Furthermore, this approach is not considered to be "pure", because the aggregates may be performing indirect IO. A service dependency could also need more work to mock than a data dependency for unit tests.
Refactoring the original example
Avoid passing another AR instance
Explicitly model the supervision policy policy as a first-class citizen, associated to a specific role. Note that you could use any modeling variants where the rule is associated to the role. I'm not necessarily satisfied with the language in the example, but you will get the idea.
interface SupervisionPolicy {
bool isSatisfiedBy(Manager manager);
}
enum Role {
private SupervisionPolicy supervisionPolicy;
public SupervisionPolicy supervisionPolicy() { return supervisionPolicy; }
...
}
class User {
public User(UserId userId, Manager manager, Role role, ...) {
//Could also have role.supervisionPolicy().assertSatisfiedBy(manager, 'message') which throws if not satsified
if (!role.supervisionPolicy().isSatisfiedBy(manager)) {
throw …;
}
}
}
Normally - Domain Driven Design calls for rich domain models, which normally means that the business logic is located in methods that represent parts of the domain.
That would normally mean that the command handler would be responsible for the plumbing (loading data from the database, storing changes in the database), and would delegate to the domain model the work of calculating the consequences of the user request.
So the "guards" would usually be implemented within the domain model.
And the last thing is, I would prefer pass a User Id rather than a User for the manager property, hence my thinking that guard should not be put in the User model.
That's fine - when a the domain model needs information that isn't local, you normally either lookup that information and pass it in, or pass in the capability to look up the information.
So in this case, you might be passing in a "domain service" that knows how to look up a UserRole given a UserId.
Are you telling me that it is perfectly valid to pass a domain service to an aggregate? At instantiation level or only to the method dealing with?
My strong preference is that services are passed as arguments to the methods that need them, and are not part of the instantiation. So the entities in the domain model hold data, and collaborators are provided on demand.
"Domain Service" is the third element of the domain model described by Evans in Chapter 5 of the blue book. In many cases, the domain service describes an interface (written in the language of the model), but the implementation of the interface is in the application or infrastructure "layer".
So I would never pass a repository to the domain model, but I would pass a domain service that delegates the actual work to a repository.
not sure if I'm just too tired and missing something so apologies in advance.
I have a php domain which I need to restructure because ended having an anemic model using services. This is because I'm not using Doctrine but Eloquent by Laravel as my mapper (reasons are due to linking to other different DB server types)
My reviewed structure needs to be something similar to do this: ( I'm only including a couple of things for this example)
Template Entity has TemplateName as VO.
The TemplateName must satisfy 2 specs. Has to be more than 3 chars long and has to be unique.
I am using a TemplateRepositoryInterface to check the uniqueness and the interface has an Eloquent implementation bounded in a service provider.
Therefore the Template Entity has a method:
public function create()
{
if ($this->meetsTemplateNameSpecification())
{
//fire events etc... saving to repo is done one step above from a service that call this class and gets $this to send tot he interface
return $this;
}
throw new InvalidArgumentException("Template name is not valid.");
}
Then my meetsTemplateNameSpecification method:
private function meetsTemplateNameSpecification($originalTemplateName = null)
{
$templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);
if($templateNameSpecification->isMet())
{
return true;
}
return false;
}
Before this restructure, a service was initiating all these and passing the RepositoryInterface to them so that was easy. However, this way I don't know how and /or where to pass or inject the interface because if I have it injected from the container to the Specification class then I cannot initiate from the Entity and I cannot inject the Spec class to the entity either because i want to be able to use it's constructor.
I find it very hard to do in PHP and Active Record with keeping a separation of concerns and not having a dependency on persistence in the domain.
Does anyone have a better structure? Let me know if you need more code please.
So far the only solution that comes to mind is to have static methods in my specification objects so that they do not need to be initiated and I can inject the Repo dependency from the container. Is this the way to go or there's better ways that work with PHP. I hate having to inject from the container to the Domain too but don't think there's any better way unless you're using a different architecture.
I think you're overcomplicating things.
Specification pattern is cool if used in a very general method signature that takes specifications as parameters, or if you have a whole family of specifications. With just one or two particular conditions to test, it might be overkill.
Also, trying to inject a Repository into a domain object (as I guess you are) may be causing you more trouble than good. String length is most probably not a domain rule and uniqueness may not be either. You might be better off checking those constraints at the Application Service (or Controller) level, directly calling the Repository there for uniqueness, which will spare you all the injection trouble.
Hello I'm new in doctrine and I don't know what to do in the following situation:
I have a controller which create a new model object "Ad". Who has the responsability of making that object persistent in the DB?. The controller because it created it? or the model it self?
Acording to MVC, the model should be the only one who deals with the DB, so I guess I have to create a method call "persist" or create an interface called model which will have this method and inject the entity manager in the constructor of every model instead of making the object persistent using the entity manager in the controller.
PD: I don't want to use any framework like Zend, CI etc.
Thank you!
The "model" is a layer, not a file or class that deals with persistence. Persistence belongs in there, but together with your Domain Objects, Services, Factories and whatever else your application needs.
The controllers (and views) are part of the presentation layer and as such should only be responsible for tasks regarding that.
If you are implementing domain objects then it is usually a good choice to use the data mapper pattern to handle persistence. If you set it up that way, then the objects themselves don't need to know anything at all about if and how they are persisted. This makes your code confirm to the SOLID principles and makes it testable.
Now you could work with your data mappers and domain objects in your controller, but a better solution for most applications is a service layer. It will allow you to reuse your service methods in multiple controllers and keep your codebase DRY. This is especially helpful if you have multiple endpoints to access your application (think normal website, admin area, API's, etc...).
A service layer class could look like this for example:
namespace MyApp\Models;
class OrderService
{
public function getOrders($limit=null, $offset=null)
{
$orders = new OrderCollection;
$orders->setLimit($limit);
$orders->setOffset($offset);
$orderCollectionMapper = new OrderCollectionMapper;
$orderCollectionMapper->populate($orders);
return $orders;
}
}
The controller. When your model is validated/ready to save.
I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.
I asked this question a while back but now I'm looking to implement an actual separation between my database access layer and the domain layer. I am also going to be working to move business logic into the domain where it belongs and out of the controller scripts.
I'm using Zend Framework which implements the Table Data Gateway and Row Data Gateway patterns for the data access layer, but it apparently fails to really define how to build a domain layer that is separate from the data access layer. I've considered using an Active Record pattern where the domain logic coexists with the data access logic, but I have the following situation that occurs at least once that I don't think Active Record will handle:
I have a single table "Person" which contains person_id and userType fields.
Each userType (admin, buyer, associate, supervisor) has specific business logic associated with it and all types inherit some basic functionality from a Person object.
I don't want to bloat the Row Data Gateway object with business logic that belongs specifically to just one type of user but I'm not certain how to construct the domain layer to represent the different types of users. For example, do I make a Person object that contains the PersonGateway object and then write wrapper functions that pass calls to the gateway object, or do I write the Person object to extend the PersonGateway object and then only implement the specific functions that I need?
Likewise, I would typically think that this is (in part) a factory problem where I need a factory method that will instantiate the correct sub-class based on userType. Is that still the best method here with Zend Framework's Zend_Db class?
Any suggestions or links to tutorials that talk about how to properly create a domain model on top of Zend_Db would be greatly appreciated.
Domain Models extend nothing. They're just plain classes you use to encapsulate business logic. They may use data access objects, so there may be a protected instance of a row data gateway object inside the class. A Row object usually represents an instance of the domain more closely than a Table object. Besides, you can always get the Table object with the Row's getTable() method.
Typically DM classes have an interface with methods corresponding to higher-level operations you can do with that class. But you don't necessarily want to surface all data access operations.
class Person {
// Zend_Db_Table_Row object
protected $data;
public function subscribeToService(Service $service) { ... }
public function sendMailTo(Person $recipient) { ... }
public function changePassword($newPassword) { ... }
}
I also blogged about this subject last spring, and wrote about it on the ZF mailing list recently.
As far as tutorials and resources, try http://domaindrivendesign.org/