Where to build new domain entities? Controller, repository, or mapper? - php

Let's say for each domain entity, I have a repository that provides an API to a data mapper. For example, if I have a UserEntity, then I would have a UserRepository that speaks to a UserMapper to persist user data in a database.
Now, let's say a form is submitted on a web page, and my controller knows it needs to create a new UserEntity based on the submitted info.
Does it:
do new UserEntity() right there on the spot, and run all the necessary setter methods according to the form data submitted, then pass the UserEntity to the repo, who passes to the mapper for insertion?
Controller creates UserEntity => Repo => Mapper => DB
turn the form data into an array, and pass it to the UserRepository who then runs new UserEntity() and the setters, and passes it to the mapper for insertion?
Controller passes user data => Repo creates UserEntity => Mapper => DB
pass the array to the UserRepository, who passes the array to the mapper for new UserEntity and insertion?
Controller passes user data => Repo passes user data => Mapper creates UserEntity => DB
Whose responsibility is it to manage the creation of objects?

I know this question is old, but I thought I'd throw my thoughts in here since the only answer hasn't been officially accepted and this may be helpful to future searchers. To directly answer your question, I'd say none of the above. I prefer to have an extra service, a "manager" if you will, for brokering the interaction between the controller and the repo/mapper objects. Each model has a dedicated manager for handling its creation, updates, and deletion.
Controllers
I consider the controller as the glue of the application. We can separate concerns all we want into as many pieces as possible, but somewhere along the line, something has to understand both the view side and the model side, and that object is the controller. That being said, I believe controllers should be skinny, so the controller's only real job is to map a request to a response. Any kind of intermediate processing should be kicked off somewhere else.
In a CRUD app, it's pretty easy to get away with instantiating new objects and persisting them in the controller, even it is done more than once, because it is only a few lines to paste. What if object creation was not trivial? I'm maintaining an application with many complex relationships and a user-submitted create often entails the creation of many objects simultaneously. This is not feasible to maintain in a controller-and-model-only environment.
Extra Service Layers
To handle this, I've created 2 extra service layers: FormHandler and Manager. Every time a form is submitted, the form contents get sent to the form handler layer. Form handlers are responsible for understanding the form data coming in and normalizing it. The form handlers can then pass off the data to appropriate manager objects for processing. Manager objects process the data and update the domain layer. They are responsible for creating models, changing models, and persisting them to the backend.
In this way, the controllers have knowledge of Request, Response, Form (possibly, if your framework supports server-side form creation), and FormHandler. Form handlers have knowledge of Form (or form data), and Manager. Manager has knowledge of Repository, Mapper, and Model. Notice, now, Managers are the sole point of interaction with Models and the Mapper, and they have no knowledge of the Form data or the Request or Response. On the flip side, the controllers and form handlers don't need to know about domain layer data or persistence.
Conclusion
With this design:
Controller -> FormHandler -> ModelManager -> Mapper
I've found all my classes are now unit-testable (even controllers to some degree) due to separation of concerns being nicely split out, and the single point of interaction is a boon for avoiding duplicate logic.
Notes
The repo in my mind is only for querying the database -- asking it if it has something, not creating new things.
My experience in this case is from using Symfony 2 and Doctrine 2.
YMMV; e.g. you may find the form layer is unnecessary, but I've found it very handy for data transformation from form/view data into something the domain models understand.

This is a tough question to answer. My two cents are on number 1 for a couple of reasons. First, it's assumed you have domain validation in your entity which could very well reject the data being passed. If that were to happen in either 2 or 3 then you've gone a few objects deep before the rejection. It may not be a lot of memory or execution time in terms of the difference between 2/3 and 1, but it is a difference. I try to fail fast.
Second, I think the controller knowing about the data being passed in as well as the objects is entirely acceptable. I agree with "fat model, skinny controller" but saying the controller can't know about the entities is making the controller too skinny for my liking.

Related

Simple model layer for a small website with tiny logic

I have struggled with an MVC concept for a long time in php since I'm not a php developer. I refactored my site several times but it still looks like a cannon pointed in a mosquito. I've read many articles, posts and answears about MVC but it still makes me confused.
Let's have a simple website with articles and comments system. Everything is stored directly in a database (information about articles, paths, comments etc.). Mostly based on this I developed my own app using MVC. Here is how it works:
Controller retrieves data from the database about an article and related comments
It creates required model's objects (current article and comments)
... and then passes necessary data to the View
View presents those data by applying particular templates for provided objects
Everything works like a charm but...
my model's objects don't need any external logic so my domain objects are bordered to getter/setter classes -I'm wondering: do I need domain objects? It's pointless to store separated objects only for getting them from DB and displaying on a website after a while, isn't it?
controller holds a DB connection passed to services and mappers for creating a model's object -but queries stored in mappers can be merged into services functionality
In conclusion, I wonder if it's not a better approach to replace three-part model with a single manager (per object) which will retrieve all necessary data from the database and will pass them in any way and form (i.e. associative array) to the View.
Please do note, that I'm describing a simple case (1:1:1) with tiny logic, where most data retrieved from database are only for a presentation purpose.
Well what you have just described is an architectural pattern for data modelling called the Data Mapper pattern.
In this pattern you separate the persistence logic to a Mapper class and leave all of the Data stuff in The Domain Model. In your scenario you mentioned there is little logic, which is fine. Logic grows as your application matures. The key point is the separation, persistence has nothing to do with logic and therefore should be moved into a different class.
The Mapper class is only concerned with persisting data (generally to whatever data store you choose), in practice you uses "Adapters", which is why in some ORMs you see a different adapter for different data stores (ie. MySQLAdapater vs PostGresAdapater... etc, implementing a abstract Adapter Interface/Base Class).
It should be noted though, in your conclusion what you describe is actually the MVC Architecture.
The Model Layer is essentially your Persistence Layer (like described above)
The View Layer is where you present your data.
Your Controller Layer is where your data manipulation ie On your domain object's data.
Typically a MVC request goes like...
a URI gets mapped to a controller::action
Action gets data, manipulates it and sends it to the view for rendering.
When MVC applications run into trouble is when your Controller accesses several different objects and needs to persist them all. The class architecture of an MVC application tends to be very heavy as the Models typically have more logic on them than in the Data Mapper pattern since MVC models have persistence tied into them (in practice).
Just as an aside, for simple projects like yours, you might want to look into simple presentation frameworks like http://www.slimframework.com/ It has no persistence layer built in, which leaves you to choose the best for your project.

MVC - How to pass data to service

I'm a bit confused on how to perform insert and update statements using MVC.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
Insert
In my controller something like:
$userservice->insert("myname","mypassword");
In my UserService:
function insert($username,$password){
$user = ORM::for_table('user')->create();
$user->username= $username;
$user->password= $password;
$user->save();
}
Update
In my controller something like:
$userservice->update("myname","mypassword",1);
In my UserService:
function insert($username,$password,$id){
$user = ORM::for_table('user')->find($id);
$user->username= $username;
$user->password= $password;
$user->save();
}
Is this good practice?
Because I see a lot of these answers where for example a user is being created in the controller and passed to a repository to save it:
Proper Repository Pattern Design in PHP?
But I don't like the idea of creating a user in the controller...
Controllers belongs to application layer and controlls only activity. In your example the activities are Create- and Update for an existing or for a new User. These operations belongs to the Domain Layer, which contains services. Thus services encapsulate the domain as a gatekeeper and provides operations for resolving domain like a facade.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
The service should provide a method to pass a ValueObject. ValueObjects are better to encapsulate lot of data (Property values for User). Inside the service, the ValueObject should be delegated to Filter and Validator. If validation didn't fail the ValueObject will be delegated to a DataMapper. The DataMapper will map the properties of ValueObject to a data-model for the UserRepository (ORM). Repositories often need another model of data, e.g. Objects versus storage mediums based on RDBMS like MySQL.
This approach should be strict to seperate the concerns between layers to improve maintainabilty and interchangeabilty. Services should be thin and acts as a delegator to Domain Objects (Filter, Validator, etc.), for example see Service Layer Pattern.
So, where should be a value object created?
I would prefer that the service provides a method for this: getEntityPrototype() by using the prototype pattern.
Be careful with naming. ValueObject is an object which have no identity. Entity is an object with identity (here id of User). For an existing User you will have have a method like getUserById($id), which should return an UserEntity. If User does not exist for given id, it should return a NullObject. To create a new User getEntityPrototype() will return an UserEntity which have no identity yet, so you will call it ValueObject or better Prototype of Entity. After setting properties (e.g. by a FormObject) and persisting this object is a real entity. In a Factory for this service you can set the EntityPrototype.
What you should think about in this case is if the classes have only one responsibility.
Controller decides about the flow of the action. If there's a need for registering a user then it registers him, but it should not define how to do it, but ask a service to complete this task and get the result.
On the other hand you should have some kind of UserManager which updates, creates and fetches users - is this single responsibility? Kinda, yes - it's managing them in a broad sense.
There's a slight problem you have with your methods' names though. You should have registerUser not insert since it's way easier to tell what it actually does.
You should Pass Data to Model. MVC is all about dividing tasks Controller - Handles Application Flow, Model - Contains all the business login Database etc and View - here you decide how to show. Basically the UI part is stored here
So the Controller should send data to Model and model decides what to do with the data. The advantage of coding this way is that in future if you want to change something in the code you know where to look, or if you ask a designer to redesign your website you only have to give him the VIEW part of code . If the designer does something that caused an error , correcting that wont take that much time. If you follow MVC properly Adding,Updating or Maintaining functionality wont be a problem

What is the right way to handle $_POST data in MVC?

I have the common MVC situation in my PHP system: the Controller receive a request from the View containing $_POST data. Now I have three ways to handle the data:
a) The Controller only calls the Model and the Model handle the $_POST data.
b) The Controller transforms the $_POST data into variables and pass them to Model.
c) The Controller transforms $_POST data into a Model's domain object and only pass the object to Model.
Currently, I am following option A, but I believe it is wrong, so I am thinking of using option C.
So, according to MVC, what is the right way to handle $_POST data?
EDIT At the moment, I'm not using any MVC framework.
EDIT 2 Generally, the same Controller handles request from a browser, a web service, an offline application, etc, or each one has it own Controller?
The best option is to use #2 approach, with some alterations.
I would write it as something like this:
public function postLogin( $request )
{
$service = $this->serviceFactory->build('Recognition');
$service->authenticate( $request->getParam('username'),
$request->getParam('password') );
}
// Yes, that's the whole method
There is no need to actually create variables, if you have used something like a Request instance to abstract the user's input.
Also, you might want to replace theRequest::getParam()method with something likeRequest::getPost()- although I have come to the conclusion that, in a correctly structured application, theGETandPOSTparameters should not share same name.
The serviceFactory which you see in the code snippet would be an object that you inject in both controller and view instance. It would let you share same service instances between controllers and views.
It is responsible for creation of services (which would contain the application logic, while leaving the domain business logic in the domain objects), which helps you isolate the interaction between domain entities and storage abstractions from the presentation layer.
About the other options:
The Controller only calls the Model and the Model handle the $_POST data.
In the MVC and MVC-inspired design patterns the model should be aware of neither the user interface nor of the presentation layer as whole. The $_POST variable in PHP is a superglobal.
If you use it with model layer, your code becomes bound to the web interface and even the specific request method.
The Controller transforms $_POST data into a Model's object and only pass the object to Model
Not entirely sure what you meant with this. Seems you were talking about instantiation of an abstraction, which would contain the user's request. But in this case controller becomes responsible for instantiation/creation of said structure, which would violate SRP.
Closing notes:
One thing you must understand is that, in context of web based MVC applications, the User of your application is the browser. Not you. Browser sends the request, which is handled by routing mechanism and disseminated by controller. And view produces the response to your browser.
And the other thing is: Model is neither a class nor an object. Model is a layer.
Update
Generally, the same Controller handles request from a browser, a web service, an offline application, etc, or each one has it own Controller?
You should be able to have single controller, that deals with all the forms of application. But that is only on the condition, you are actually using same application for all 3 use-cases.
To do so there are two conditions:
you need to abstract the Request instance, that controller receives
the view should be instantiated outside the controller
This way you can have one application to fulfill all the requirements. Only thing, that each variant has different, is the bootstrap stage, where you create the Request instance and select the proper view.
In the situation, that you described, the changing part would actually be the view, since a REST or SOAP service would be expected to produce a different response than an ordinary web application.
Once upon a time was the three tiered application architecture.
It all depends on your MVC framework. Normally, the Controller does the link between the user and the model layer, which manipulate domain objects.
In the early days of MVC in PHP, the model layer was actually just the domain objects, called models for that purpose.
Some prefered having so called thin models, which only provide an OO representation of the data, (which simplifies persistence). In that case, the controller would regroup the so called actions, containing the bulk of the processing associated with an HTTP request (fat controller).
Others embedded most of said processing in the object model with dedicated methods (fat model).
However, at some point, you have to analyse the content of the query to sanitize and validate it, and this depends on how your view will format the request. Sanitization might be a controller task (this request should only contain these values), while validation is definitely a model task (values should be of these types).
An interesting question is: how do you deal with actions impacting several domain objects? Where do you put the logic for that?
Nowadays, the model layer is composed of services segregating the domain objects from the evil grasp of the controllers, to limit the dependencies between the layers to their respective interfaces only. This is where most of the request processing is done.
Symfony2, for instance, provides a sensible answer to this question: each step of the processing of a request is implemented in a dedicated piece of code, which could be described as the following:
the request is first turned into an object
that object is routed using a routing object
it is handled to a controller
the controller pass the request to the service concerned by the action, which build the response object
The service job is then broken in several steps:
validation (using a dedicated object which rely on rules described in a separate file),
construction/updating of domain objects (using serialization to/from db if necessary),
selection of a template for the response,
population of said template with the relevant data from the domains.
CakePHP is another popular framework which follows similar concepts: simple controllers, and services encapsulating domain objects.
See this question for a better insight on the general concepts.
See this other question for other answers.
Thanks to tereško for his invaluable input on the matter.
i am using Zend and following
the 2nd option .
Example a Registration form
step- 1 the forms sends me the post value to the specified controller
step -2 i will validate the form values for example ( mail and url and empty post values ) through server side validation .
step -3 send the checked post data either in variable or has whole to the model .
step 4- controller calls the model .
step -5 the models inserts the post values and creates a new user .
I think your second option is better regardless of framework or approah you use .
note - same controller can handle everthing depends on your application logic .
but i prefer to keep different controller for differnt user request and user types
it helps in keeping code readable managebale .
Look at some MVC frameworks.
For example, in Yii you can write such code inside action:
$model = new Model();
if(isset($_POST['Model'])) {
$model->attributes = $_POST['Model'];
}
Note, that all attributes of your model must be passed through validation rules. In Yii validation applies during (actually, before) $model->save()
See:
http://www.yiiframework.com/doc/guide/1.1/en/form.model#securing-attribute-assignments
http://www.yiiframework.com/doc/guide/1.1/en/basics.mvc
'C' is best option. You should not let raw $POST data go in model as model is supposed to be generic handling store and load operations mainly.
Example : same model can be used web interface and Web services. On Web $_POST is valid but for web services its not. So model doesnt care how data is received but only how to store and load it.
Yii is definitely a clean implementation of MVC.

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.

Data and Form validation in MVC architecture

I develop most of my web applications using CodeIgniter, and have always took the approach of validating form data inside the controller, using the built in Form Validation class, before sending this data to the Model to be used, e.g insert the data into the database.
However, I keep hearing the "skinny controllers, fat models" line - and I'm wondering if these validation checks should be placed inside the model.
Three things strike me when I think of using this approach.
How can different error messages be shown to the user, without returning seemingly ugly arrays or objects from these model functions? e.g A duplicate email on signing up for an account. Would the method responsible for adding a user in the model have to return an array or object to indicate if the insert was successful, and any error messages?
By doing the validation checks in the model, checking variables supplied to the methods from the controller (not POST data), I will lose the use of the Form Validation class, a class that I find very useful in my projects. Would you suggest that I write a class, or library that can be used like a CI library to mimic the Form Validation class, but for supplied variables, and not limited to the POST data?
Following on from that concern...as the POST data would have to be validated for existence (isset($_POST['myvar'])) before being passed to the model, should the rest of the validation not just be placed in the controller as well?
Any suggestions, advice, opinions will be appreciated!
Your original issue comes from fact that CodeIgniter's interpretation of MVC is quite appalling. This framework pretends that View is just a template, and Model is just an ORM ( which some say, should be classified as anti-pattern ). Which is completely wrong, and forces bot business and presentation logic inside the Controller.
But lets leave View aside.
Model in MVC is not a class or an object. Model is a layer, which contains all the business logic. It is actually comprised of instances from multitude of classes. The two most prevalent groups are Domain Objects [1] [2] (this is, what people people usually call "models") and object responsible for information storage and retrieval - usually DataMappers. The model layer also contains standalone components (both your own and 3rd party) and higher level abstractions - services.
What you have as Validation class, might be considered to be a standalone component, which can either be used by Domain object to perform validation, or expect a Domain object to be passed in for validation .. depends on your implementation.
In your situation i would handle this at the service layer. Which would either provide the instance of View class with a valid domain object, or an object, which represents the error.
Some reading materials yu might be interest in:
GUI Architectures
AnemicDomainModel
Tell, Don't ask
Then again .. what the hell i know of it all ..

Categories