How to create Business Layer object with Dependency Injection? - php

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.

Related

Best practice of Instantiating a DAL object in MVC model implemented in PHP

I am learning the popular MVC and trying to implement it in PHP. I am designing a framework with a pure OOP fashion (though I am not expert in PHP's OOP ability. I only have moderate knowledge about it). An example implementation of this framework as shown in the following figure.
In this framework I added a Data Access Layer, DAL, (a class to deal with the connection, executing query and transport to and from the database) to abstract the physical database from the rest of the system to easy change of the data source. If a system is only bind to one database of one particular type, this layer is expected to presented in the system using only one object with one connection to the database. And this object will be a dependency for all the Data Mapper objects (i.e., User mapper, Product Mapper).
I am looking for your comments on where to initiate the DAL object in the system. I can create the object in the front controller (index.php) and transport all the way to Data Mapper objects. But it is an anti-pattern according to Here and Here. Even for the same reason, we cannot initiate the DAL object within the factories (Factories can be separated in multiple classes for handling complexities as per Clean code approach ). I cannot use Singleton as that is also going to create lots of problem according to this. So, in your opinion, what is the best practice and place where I can initiate this object and pass it to Data Mapper objects?
N.B.: I disregard the View Logic here as my concern do not have any relation with Views.

Approach to adding persistence code in Symfony when not using Doctrine?

I am interested in learning about best practices for persistence code in Symfony2 when not using an ORM and not having objects represent my table rows.
One way would be to create a model / dao directory and store classes with wrapper methods (e.g. getPost($id), addPost($title, $content) for a blog post). Then access these methods inside the service class which has similarly named methods as getPost($id) etc. which might just be calling the wrapper methods in the model / dao classes or doing a bit more work (preprocessing data to send to db, postprocessing data received from db).
Do you think this is a reasonable approach or is there something better you can think of? Thanks.

PHP Dependedncy Injection & Complexity

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.

Should I Create Domain Object Defaults in my Service Layer?

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.

MVC and the Repository Pattern: Roles of Controllers, Models, and Repositories?

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.

Categories