Reputation: 47
I'm not using an off-the-shelf framework and don't particularly want to (nor d I want to go into the reasons why...). Anyway, onto my question(s), I hope it make sense....
I'm trying to get my head around what should go in the model and what should go in the controller. Originally I had the impression that a model class should represent an actual object (eg - a car from the cars table of a database) and model properties should mirror the database fields. However I'm now getting the feeling that I've got the wrong idea - should an instance of a model class represent an actual item, or should it contain a number of methods for doing stuff - sometimes to one car or sometimes to multiple cars based on my example earlier.
For example I want to get all the cars from a the database and show them in the view. Am I right in think it should be along the lines of this?
Controller File
function list() {
$cars = $this->model->get_all();
$this->view->add($cars);
$this->view->render('cars-list');
}
Model File
function get_all() {
// Use a database interaction class that I've written
$cars = Database::select();
return $cars;
}
Now, if the car had a "status" field that was stored as an integer in the database and I wanted to change that to a string, where should that be done? By looping the SQL results array in the get_all() method in the model?
Also, where should form validation live? I have written a validation class that works a little like this:
$validator = new Validator();
$validator->check('field_name', 'required');
If the check fails, it adds an error message to the array in the Validator. This array of error messages would then get passed to the view. Should the use of my validator class go in model or the controller?
Thanks in advance for for any help anyone can offer. If you know of any links to a simple MVC example / open source application that deals with basic CRUD, they would be much appreciated.
Upvotes: 3
Views: 804
Reputation: 10781
I would highly recommend you take a look at "Patterns of Enterprise Application Architecture" by Martin Fowler. It has a good explanation of what each of the separation of responsibilities are for each of the MVC components (plus a lot of other useful patterns).
In a pinch, wikipedia has an okay explanation of MVC.
In short, the structure you've setup is correct. You're controller is informing the model that some event has occurred, the model is reacting to that event, then the view is using the model to represent the state of the system to the end user. The validation should be performed within your Model, since it is responsible for maintaining the correct state of the system. You may also have some client-side validation which is strictly there to reduce network traffic and provide a nicer interface for the user.
One thing to keep in mind is that you want to keep your business logic within the Model. You want to try to avoid what's called an anemic domain model. This is pretty typical when your model is just a thin veneer over a database.
Another book I would recommend is by "Domain-Driven Design: Tackling Complexity in Software" by Eric Evans. The focus with DDD is that "the primary focus should be on the domain and domain logic".
Upvotes: 4
Reputation: 31730
The general breakdown of responsibilities in MVC is generally as follows:
As I already mentioned, many people think the model is little more than a data access layer. You can usually tell when people have followed this design philosophy because the result is models that don't do a lot, and controllers that do too much (the so called Fat Controller anti-pattern). The problem with this approach is that if you want to reuse portions of your codebase in some other project, then you can't take the model over to the new project without taking a big chunk of the controller along with it. Controllers are generally considered to be application-specific and therefore non-reusable. Models, on the other hand, embody entities in your application, and you might have several applications that require the use of the same type of entity (Blogging software, e-commerce storefronts and message boards are all very different applications, but they all need to implement users).
Generally, you want fat models (which can be easily reused without copying code not implemented in the model itself) and skinny controllers (that can easily be replaced when you need your model to do something else).
Validation kind of throws a spanner in the works though, as it's what's called a cross-cutting concern. The idea of MVC is one of separation of concerns as it aims to characterize code as falling into one of 3 major categories (business logic, presentation logic, glue logic), but validation doesn't easily fit into any of those. Good arguments can be made for it being both business and glue logic, and if you want to display validation errors to the user, then it's also got an element of presentation logic as well.
Generally, I implement a level of validation in my models, generally fairly basic sanity checks (such as requiring that integers are actually inter values and the like), and implementing a separate set of classes for doing full validation of input. I'll invoke the validation classes in my controller and if validation fails there I'll present the results to the view. If it succeeds then the data gets sent to the relevant model for processing. I suppose you could call validation "utility logic", something you need to do in a regular basis that you can't really tie to any one model, view, or controller.
Upvotes: 4
Reputation: 3921
First of all, if you don't want use any PHP framework, you can look at their sources and get good ideas about some features implementation.
What about a validation, I think that it is a business-logic feature, so it must be placed at the controller layer. (edited: that is bad idea)
Upvotes: 1
Reputation: 2393
If you want the status field to be treated as a string within your application, you don't want the persistence detail of having it as an integer in your db to creep out from the car class. In its interface it's a string and as such it should be treated.
So, I'd use a getStatus() method in the Car class, which you'd invoke AFTER the getAll(), whenever you'd need it. You'd be delegating the cast at item level. It's better not to let the rest of your application to know that you have an integer at the lowest level. Expose a string from car and live on with it within the rest of your application.
As for the validation, I'd do it in the controller. You get stuff from the view and make sure it's good enough for your model. Unless it's a check which specifically needs to be made within the model (IE business relate constraint).
Upvotes: 1