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
Related
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.
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.
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.
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/