7

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

Community
  • 1
  • 1
randomizer
  • 1,614
  • 3
  • 14
  • 31

3 Answers3

8

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.

Mamuz
  • 1,692
  • 12
  • 14
  • Ok thx for this nice explanation, one question though: where do you create your value objects? I know you shouldn't create objects in your controllers, so how do you pass them from controller to service? – randomizer Mar 24 '14 at 07:36
  • I added a new part 'So, where should be a value object created?' to answer your question – Mamuz Mar 24 '14 at 19:51
2

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.

Uriziel
  • 662
  • 4
  • 15
0

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

Tabby
  • 389
  • 1
  • 11
  • I woudl disagree with putting "all the business logic" into the model. It's just as wrong (or just as right) as putting it into the controller. MVC alone is nothing, for a larger application you should consider additional layers. – ckonig Mar 27 '14 at 19:08
  • @ckonig For me model is also a folder which consists of a group of files that help achieving the business end. But i always feel i am missing something as my goal is reusing code not only in the same application but also other applications and i make my own MVC . If you could recon a link to me that reflects your thoughts about a MVC ; i would love to learn from it. I'm also in the process of making a large application, this would help me make the app even stronger. Thank you..! – Tabby Mar 28 '14 at 05:36
  • Those two are specific questions for ASP.NET, but they go in the right direction: http://stackoverflow.com/questions/235233/asp-net-mvc-should-business-logic-exist-in-controllers and http://stackoverflow.com/questions/7777770/what-is-the-best-place-for-business-logic-in-asp-net-mvc-when-using-repositories - Personally i like to have Models that represent data in the datasource (Persistence Models) and ViewModels that hide the datacompelxity for the views. – ckonig Mar 28 '14 at 08:27