In MVC, Where Do You Draw the Line Between a Controller and Model

in MVC, where do you draw the line between a controller and model?

The line between controller and model is actually quite clear.

Model is your application's heart. It contains the business/domain logic required to solve the problem your application was written for. The Model is usually layered into several other layers, e.g. persistence, services, domain, etc. It's a common misconception that the Model is just the database, as much as it is a common misconception that the database should be an ActiveRecord.

The controller (and the view) are part of the presentation layer. A controller's sole responsibility is to receive and handle user input directed towards your application and delegate this to the appropriate parts in the model. Nothing more. It should not handle complex application flow or code of your problem domain. You want controllers to be skinny and models fat with logic. The Model should not know about either C or V and you should be able to swap out V and C for a different presentation layer without having to touch your M.

See MVC Excerpt in Patterns of Enterprise Application Architecture

Drawing the line between the model and the Controller

It is a part of Domain Driven Design.

The Domain is the sphere of knowledge that defines the area that the application is attempting to work with and solve problems for.

The Model layer is considered the Domain layer. It is here that all the rules that define the Domain or business logic are kept. The model acts as a filter between the real data and the rest of the app in a way that defines the domain.

The implementation details of the Domain (mySQL or MSSql or Webservice or Xml file or external web page or whatever) are hidden by the Model.

The Controller is just the messenger. Its job is to take messages from the user and pass them to the Model. The Model comes up with a reply and the Controller works out the best way to pass this on to the user.

The View is like the make up artist, just making sure that the data looks good and presentable for the user.

The website that you are scraping could be considered to be part of the Domain. This site contains knowledge that defines the world that your app is defining. The screenscraping process is sculpting that knowledge in a way such that it will relate to the rest of the world view that your app is defining. The Controller doesnt care where this knowledge comes from, it will just pass the message on to the View. The View will fuss over the data and make it pretty and send it off to the user, who is completely oblivious to the whole process and just sees a pretty web page!

Is ASP.NET MVC is really MVC? Or how to separate model from controller?

I think it could be either way. Here would be an implementation is ASP.NET MVC that keeps the logic like you had in your first example.

Model (Respository)

Function switchOn() as bulb
if !bulb.lightOn then
bulb.lightOn = true
end if
return bulb
End Function

Function switchOff() as bulb
if bulb.lightOn then
bulb.lightOn = false
end if
return bulb
End Function

Function Motion(senseMotion as boolean) as bulb
if(senseMotion and !bulb.lightOn) then
bulb.lightOn = true
end if
return bulb
End Function

Controller

Function PressSwitchOn() as actionresult
return view("Bulb", lightRepository.switchOn)
End Function

Function PressSwitchOff() as actionresult
return view("Bulb", lightRepository.switchOff)
End Function

Function SomethingMoved(byval hasMoved as boolean) as actionresult
return view("Bulb", lightRepository.Motion(hasMoved))
End Function

No business logic in my controller, it is simply passing the state from the model to the view. Am I in the ballpark of your example?

To answer questions.

  1. Yes, I think you understand it pretty well
  2. No, I would disagree. One of the benefits of ASP.NET MVC is that it is extremely flexible in your implementation. You could put all of your logic in your view if you really wanted to (why, oh why would someone want to do that), but you have the option.
  3. I think to draw the lines, keep the DRY principles in mind. If you have logic repeated multiple times, make sure its part of the model or some custom business class that you can reference from one place. That to me is one of the main driving principles of designing a MVC app.

Rails MVC - Should database search logic go in the model or the controller

As many thinks in IT and in life, It depends of the scale and the goal.

Considerations:

1) For design: If you see you are violating DRY in your controllers many times, its probably time to move your logic to models.

2) For performance: Since controllers are loaded more than models, Logic in controller tend to performs worst.

And not less important: Unless you are doing something very trivial, and you db has a few thousands rows, do NOT use db for text search. Instead, use a search engine like Solr, ElasticSearch, Sphinx, etc.

Where to place authorisation within an MVC web application?

After a lot of searching and researching I think I found the answer to my own question.

To satisfy the requirements I needed to implement "Attribute Based Access Control" (abbreviated to ABAC). It is also called "Claims Based Access Control" and "Policy Based Access Control".

ABAC uses four inputs to reach a decision on whether the current user is allowed to do what they're trying to do. The four inputs are:

  • Subject - This is the user object. It would contain the user ID and their role(s).
  • Action - This would be the controller name and the action name.
  • Resource - This would be the blog post object in the example I gave.
  • Environment - This would probably be fixed in the example I gave. But you could use this to differentiate between a web application, an API or a scheduled task.

The check should happen inside the action. Here's a quick PHP pseudo code example:

class PostsController {
public function updateAction() {
// get the post
$model = new PostsModel();
$post = $model->findById($_GET['id']);
// check authorisation
$authorised = $this->authorisor->check(
$this->user,
"PostsController::updateAction",
$post,
APP
);
// build response etc.
}
}

It should be obvious why it needs to happen inside the action; there is no resource (the post in the example above) to check against otherwise!

PHP MVC - How can Controller and View access same instance of Model?

Well .. fists of all, there are no "models". Model in MVC and MVC-inspired design patterns is a layer, that contains multitude of structures, just like presentation layer contains controllers, views and some other things.

That part aside, your issue is that you are having separate instances of those "models". Instead both controllers and views should share same factory, which can produce and cache the instances.

The optimal solution would be for you to have services, which represent parts of model layer and through which controllers and views interact with model. A factory would initialize the service first time when it is requested, and then provide the same instance on any repeated request.

class ServiceFactory
{
private $cache = array();

public function create( $name )
{
if ( array_key_exists($name, $this->cache) === false )
{
$this->cache[$name] = new $name;
}
return $this->cache[$name];
}
}

This is the "extremely dumbed down" version of service factory.

At the bootstrap stage you initialize the service factory and then provide both the current controller and current view with instance of it, by injecting it in the constructors of said instances.

Where to include SMS-functionality in an MVC application?

I've developed more than a few ZF apps that use Twilio. I tend to either use their PHP helper library in the controller, or (if it's anything other than a simple application) wrap their helper in a service class: Application_Service_SMS.

At that point, sending an SMS message should look like this in the controller:

$sms->send($from, $to, $body); //$sms is a service object of the twilio lib

But that's only the sending part of the question, how do you get $body? Since you're running in an MVC framework, my suggestion would be to separate the two layers (model and view), just like you would do at any other point.

If the model determines the content of the messsage, do something like this in your controller:

$this->view->model = $model;
$body = $this->view->render('sms/' . $command . '.phtml');

You'll have to make sure the body is less that 160 characters (or split on that, and send multiple messages). And you've made the SMS message editable without changing your model (since the message is really part of the view layer).

And since with Twilio you can send SMS messages as part of a voice call's TwiML, you can also reuse that message template like this:

//inside a TwiML script
<Sms>
<?php echo $this->partial('sms/cmd.phtml', array('model' => $this->model)); ?>
</Sms>


Related Topics



Leave a reply



Submit