I am building a MVC application with Zend Framework. The Model includes separate Domain and Mapper layers, and a Service layer sits on top.
For some of my Domain objects, when I create a new instance I need to create other Domain objects which are composed by the first object. For example, when I create a new Organisation object I might add an Employee object (based on the current user), and a Location object (based on the current user's location).
So far I have been creating these in the constructor of the parent object (in this case, Organisation). This is OK, however it does create unnecessary dependencies between Organisation and it's children.
I would prefer to create the children in the Service layer, but am I letting myself in for trouble if I do this?
After reading Martin Fowlers (POEAA) chapter on the Service Layer, I think it comes down to whether this is Domain Logic or Application/Workflow logic. Seems to me that it's borderline... (Note that my service layer is already more than just a facade).
As I understand from your description, currently both the Employee and Location are mandatory dependencies for every instance of Organization. When you are creating this dependencies in the constructor, you create two problems here (thy are kinda like two ends of same ugly stick):
The Organization class becomes tightly coupled to the names of "Employee" and "Location"
It becomes very hard to test the behavior of Organization instances, because you have no direct control over its dependencies. You are unable to isolate the "unit under test".
Note A: actually an organization require a collection of employees/members, with minimum number of one. In this case a collection of domain objects would seem like a better choice from bit aspects of logic and API implementation.
To avoid these problems there are two solution for situation when you have to create a complicated object graph:
Use a factory (supplemented by properly implemented DIC), which creates all the requirements of your Organization class and injects them, when you are constructing new instance.
Create the create all the dependencies and then inject them manually in the Organization, when instantiating the object.
Note B: to create domain any domain objects within a service you should be using a factory for said objects. To facilitate this, you would have to inject a domain object factory in the constructor of any service, that you instantiate. Otherwise you just end up with classes that are coupled to names of other classes.
The choice would depend on what else you want to do with the Employee EmployeeCollection and Location instances in that and similar cases and on what style you prefer.
If you are doing extensive and very specific manipulation with these dependencies, then they should definitely be instantiated separately (via a simple domain object factory) and only then injected. If you are only creating an object graph, the the DIC-based factory would be favorable solution.
P.S.: I would recommend for you to watch the The Clean Code Talks - Don't Look For Things! lecture.
Related
I have been searching for an answer in this topic but I haven’t been able to find a satisfactory one like in other topics, where the consensus is solid.
The situation
To keep things simple: I am implementing a custom Dependency Injection Container into one of my current projects (I know, I should use an already built one, but I’m doing it with learning purposes; so answers like ‘use this func of that container…’ are not useful) and I’ve stumbled a problem with instantiation of new elements inside a collection.
The problem
Imagine that I have a complex object, for example a car. This car has several dependencies (engine, axis, seats, airbags…) that have, at the same time, their own dependencies, and so on.
It is not a big issue to make the DiC (via autowiring or using a config file) build the object graph and inject all the dependencies with a simple line of code like:
$car = $container->get(‘car’);
The problem arrives when I build a CarCollection, which is a simple class that wraps an array of cars. The issue comes when I try to use a method that populates the collection with all the cars that exist in the database. It’s obvios that the collection should be able to create the Car objects on the fly when we call the “getAll” method from the database.
The code would be something like this:
public function populate(array $filters) {
$all_data = $this->dao->getAll($filters); // Call the data access object to query all cars.
foreach($all_data as $data) {
$new_object = $this->container(‘car’); // create a template object
$new_object->setData($data); // set the info.
$this->items[] = $new_object; // Add to the collection.
}
}
If car was not such a complex object it would be easier, because I could pass the car fqcn as a parameter for carCollection and use it in every iteration. But that’s not possible for a very complex object (or if I want to instantiate different sub types of the object - for example: lorry, pick-up, van…- depending on information from the database).
The question.
Regarding the collection being aware about the container: does not it break the purpose of the DIC phylosophy?
I guess not on one side, because I am using PSR\Container to type hint the container I pass to the collection (which loosens the coupling). But it breaks the idea that the container should not be coupled with the domain model at all.
The only alternative that I have thought about is substituting the creation of one new object for each iteration with a cloning from a prototype object that lives in the collection as a property. But we all know cloning in php can get really tricky and very difficult to debug (Or worse: very difficult to even know that there is a problem going on).
Similar issue.
PS: I have the same problem when I try to do lazy loading using Porxy objects: I need the proxy objects to have access to the container if I want to instantiate the full object later, which also breaks the principles of a DiC.
Thank you all.
I think the core of your issue comes down to this:
The issue comes when I try to use a method that populates the collection with all the cars that exist in the database.
The composition of object graphs of application components should be independent of any I/O, as described here and here by Mark Seemann. This means that the structure of those object graphs can't (and shouldn't) change based on changes in your database.
It seems to me that your Car object is a Domain Object, rather than a (Domain) Service. It would, therefore, be better suited to return a collection of Car instances from a service, rather than injecting the collection directly into one of your application components.
I need the proxy objects to have access to the container if I want to instantiate the full object later, which also breaks the principles of a DiC.
It's generally considered to be a bad practice to let application code depend on the DI Container. This a a pattern known as the Service Locator anti-pattern. There are many reasons why Service Locator is considered to be a bad idea, but it's important to understand that the list of downsides of Service Locator do not apply when the DI Container is used in the application's startup path (a.k.a. the Composition Root). A DI Container used within the Composition Root, is not an implementation of the Service Locator anti-pattern.
When your proxy classes are defined within the Composition Root, it's perfectly fine to let them depend on the DI Container and you won't violate any software principle or practice.
I've been investigating a lot about dependency injection theory and it makes great sense except for the fact that it seems to introduce complexity/bloat in certain scenarios.
Firstly, it is assumed that a DI Container instance is never passed into any object. Bad practice and all that...
For example: Consider a "user" class that relates to all other business objects created in the system by/for a specific user.
If a user instance is to be deleted, all related objects (i.e. records, files, images, etc.) also have to be deleted. Does this mean that an instance of each and every dependency is to be injected into the user instance to allow for the lookup and deletion of all related objects? i.e. an instance of ImageMapper (or ImageMapperFactory) must be passed in in order to delete all images created/uploaded by the user instance being deleted?
If not, is such a scenario a good example of where a service locator should be used?
I find it repeated over and over again in the articles & tutorials that a programmer must avoid using "new" within any class like the plague. However, is this really feasible for instances of controllers that may need to create a variety of views or the like?
A concrete example of adherence to the SOLID mantra, at least as far as DI is concerned, would be appreciated... One that makes it clear how one would either stuff instances of ALL required dependencies into a controller class or how best instances of such dependencies would be located or created?
I don't know PHP but I'll try to explain some things so your question doesn't get neglected, so bear with me. ;-)
I find that dependency injection works best by separating your application in layers:
Presentation Layer - Some (user) interface that provides interaction with your application.
Business Logic/Service Layer - The actual behavior of your application.
Persistence/Data Access Layer - The layer that stores/reads data from a back-end (try searching for repository pattern).
These layers all transfer data to each other in a structured way, using domain models. These models can be for example a user and an image.
When your application logic states that a user's images are to be deleted when a user is deleted you'll want this in the middle layer (Business Logic). The business logic layer calls the data access layer in order to delete entities.
Let's demonstrate using Python (I hope you can read that).
# Define a class that manages users.
class UserService:
# A constructor accepting dependent DAL instances.
def __init__(self, user_repo, image_repo):
self.user_repo = user_repo
self.image_repo = image_repo
def delete(self, user):
self.user_repo.delete(user)
self.image_repo.delete(user.profile_picture)
The repo arguments that go in the constructor are instances of repository classes, this is dependency injection (constructor injection).
The important thing to remember is that an object doesn't instantiate another object, it accepts instances of objects.
So I've been studying the role of the repository pattern as a means of decoupling the persistence layer from my models in an MVC framework. Prior to this, I might have my UserModel calling active record methods directly in order to store/retrieve domain objects.
Here's a sketch of what I'm thinking in regards to the call stack in a request that should create a new User:
Here are my questions:
Is this a correct implementation of the repository pattern?
I understand that the controller should take the user's information from the request and pass it into the model. How does that usually happen? Should the controller create a User object and then pass that into the model? I sure as heck don't wanna just pass in an array of values into the model--nor do I want to pass in 15 arguments to the model method that creates a user.
In order for this pattern to really work, it looks like to me I would need to have a domain object that is just a simple data structure with no behavior and then if I'm using an ORM, I would have an ORM object which will describe how the object is persisted. Initially I resisted this because it feels like duplicate code, but if I'm really separating persistence from the business logic, this would be needed right? For example, what if I went with an in-memory store? I would no longer use the ORM object.
Am I thinking correctly here? Is this acceptable. Please help me connect the dots in my head.
1. Is this a correct implementation of the repository pattern?
I'm not sure where you been doing that research, but you have got it wrong.
Repositories as for separating the domain objects from data mappers.
There no such thing as "models". Model in MVC design pattern is one of the to main layers: presentation layer and model layer.
And the repository pattern is incompatible with active record (anti)pattern, which combines domain and storage logic in single instance, thus causing a major SRP violation.
To use a real world example for, when and how to use a repository here is an example:
You are creating some document management tool, where said documents can come from several sources (for example: local SQL database, SOAP service and cache). In this situation you create a repository, which deals with the "routing" of storage. It is the part of application, that decides which data mapper to use for storing/retrieving each document.
The goal of repository is to separate the domain logic from the interaction with storage. For the system, that was described above, a repository would also let add new data sources, without need to rewrite large amounts of code (if any). You could just add another type of mapper for the document.
2. Should the controller create a User object and then pass that into the model?
To begin with, controller itself should not create anything. Instead your controller should use a factory for acquiring instance of the object that you need. This factory can be provided to the controller through constructor or some other method. This is called: Dependency Injection (to learn more about it, watch this lecture).
Also, as noted above, model is a layer, not any specific class or object. The responsibility of controller is to alter the state of model layer (by passing data to it). You could interact with domain objects and mappers (or repositories) directly in the controller, but it would mean leaking some of the business logic in the controller. It is recommended to instead use services, which then manipulates said domain objects and storage related structures.
As for the issue with 10+ parameter, that you would require for creation of new user account, let's assume you have action with following footprint:
public function postUser( Request $request )
{
....
}
If the action gets called with specific Request instance, you have two options how to deal with large amount of parameters:
Wrap the instance in a decorator, which would let you call a single method for forming the data from request in a specific array. Then you pass this array to the service(s).
Form the array inside the controller's action and pass it, where th data is required.
The former solution is more suited for large scale applications, where such formation of data would be required repeatedly though-out the code. But in a small/medium projects the second option is the common-sense approach.
Thing is, the job of the controller is to take the user's input, and distribute it to the model layer and current view. And formation of such array fits right-in with this mandate.
3. (..) main object that is just a simple data structure with no behavior and then (..)
No. Domain object is not "simple data". It is where most of the domain business logic resides in the application.
And forget about magical ORMs. First step for implementing a repository is to separate the domain and storage logic. Domain object handles the validation and business rules, mapper deals with persistence and data integrity (small example here).
Another thing that you must realize is that repositories for web application do not really interact with in-memory persistence (apart from cache). Instead your repository would be juggling mappers for different data sources.
Should the controller create a User object and then pass that into the model?
I'm not sure what you mean by "pass that into the model" -- the User object is the model. "Controller" and "model" represent different layers in the design, they are not specific objects, and there shouldn't be a separate UserModel object as you mentioned.
The repository interface itself is generally considered part of the model, though the domain objects shouldn't be saving themselves -- this should be done in the controller.
Your controller's job would then be to interpret the request and create a User object, then use the repository to save the user:
$user = new User(...); // based on Request
$repository->save($user);
it looks like to me I would need to have a domain object that is just a simple data structure with no behavior
This is not true, you can and should encapsulate behaviour in your domain objects. As for how persistence is actually implemented, a good ORM should take care of most of the details and you shouldn't have to create additional classes by hand.
I am reading factory method pattern as I have some issues related to it but I am unable to understand it from core. As per definition stated here
The creation of an object often requires complex processes not
appropriate to include within a composing object. The object's
creation may lead to a significant duplication of code, may require
information not accessible to the composing object, may not provide a
sufficient level of abstraction, or may otherwise not be part of the
composing object's concerns.
I can understand the concept of duplication of significant code, but I am unable to understand the other concepts like it states
It may require information not accessible to the composing object
How a class can contain the infomation which ic not accessible by composing object. As for as I understand it may be any private datamember of the class. But if any thing is private then how object creation process needs that information? Similarly other two point
It may not provide a sufficient level of abstraction, or may otherwise not be part of the composing object's concerns.
Can any body please here describe these precisely and show my some code stuff so that I can understand the concept
The idea of factory pattern is to create load classes and create new objects dynamically. Quite often it is done as a static class (such as here, in the official PHP documentation), but some frameworks use factory pattern as a way of loading objects within MVC objects, for example when you want to load some data in view through a model.
The idea of factory pattern is efficiency and resource management. It loads a file only when it's not been loaded yet and returns the newly created object.
(Note that the example in PHP documentation is not ideal, it would be better to check if the class has been defined and if not, then attempt to include the file instead of using include_once())
when it comes to use an external resource in our object there alternatives for its creation come to mind :
To create the object using its constructor
To ask another object to create it for our object (Factory and
Factory method pattern) .This way our object doesn't know how to
create the external resource but it should know who to ask for
it.(it needs to hold a reference to the factory or knows the type of
the factory in case of calling a static factory method)
To inject the external resource using an IoC (inversion of control)
container.This way our object doesn't to know nothing about neither
how to create the external resource nor who is responsible for its
creation.Actually this method is making factory patterns obsolete.
Imagine you are writing an API through which users can create and use a certain object. Internally, in the API framework, you want to register your object in some services, listeners, database...
Here you have two different ways of dealing with the situation:
You either let the user create the object and take the responsibility of registering it in the services, listeners and database which should be exposed (public).
OR
You want to provide a public factory class that will create the object given certain parameters and will take care of doing all the necessary initialization for you.
The second scenario is the best way to hide all the complexity of creating such objects in your system. This also has a big benefit of hiding the services, listeners and databases needed to register the created object.
My goal is to keep my framework as decoupled from my application as possible (though I know it's not entirely possible).
I have several different common types of Models that I use in my application...mappers, data objects, and value objects. For example, UserMapper takes a UserData object and gather info from the database and then maps it into a UserValue object for use within the Controller.
That means that these models have the following dependencies:
UserMapper: needs UserData, and a way to build UserValue(s)
UserData: needs Db (from framework)
UserValue: needs nothing
Do I include in my framework's DIC methods to create Mapper objects, Data object, and Value objects, so that the dependencies could be automatically inject? Or do I create a separate DIC / Factory to handle the Business Layer stuff?
A dependency injection container could handle the creation of all objects. This includes your DIC using factories to create specific objects that use the factory pattern.
I like to load my DIC up with closures that create the objects. This way all objects are lazy loaded only when requested, but I can still have a lot of flexibility when it comes to object creation.
You could write in a way that your datamapper is given a blank uservalue object, and then initializes the object's data based on DB data. The alternative is to create a tight coupling between your datamapper and uservalue classes by having the one create the other by itself.
Trying to separate you framework from your business logic shouldn't mean not allowing the two to touch, just that no business logic code goes in to your framework's code. using a DIC to create objects that are used for business logic doesn't mean that there is business logic in your DIC.