Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

TLDR: Are models supposed to be application-dependant and totally worthless when starting a new application, or are you supposed to design models independently so that they act as stand-alone classes/libraries? (This would make little sense with a framework such as CodeIgniter where you extend the CI_Model which obviously won't be there in your Kohana project.) I've also read several similar questions to some of my points here, but this is the main point which I have not found an answer to.

I've been using CodeIgniter for quite a while which introduced me to the MVC pattern. Even though it took a while to get into it has paid off the more I've read, reflected and inspired myself about it, however there is something that has always been constantly annoying me; how to properly put together a valid, efficient and working composition of objects.

Considering the three different workareas of the MVC structure I use (controller, model and library - yes, I said library, for independent class inclusion), I've had a hard time deciding whether the model should act as an independent class itself or only act as a structure to the application as the so-called 'black box', 'business model' or 'fat model'.

I do keep my controllers 'skinny' and try to do so because all documentation I've read have tried to point that out, but since the controller is application-specific and not independent (in such a way that I could just take it from the application and apply it to another totally different application), I've come in confusion if the model is supposed to act in a similar fashion, simply being a pair of organized 'fat' classes being tied to the main application, losing all their worth if moved to a totally new project.

And exactly this is the core of my problem and I really need to get a crystal-clear definition about this. To help you further understand what I mean I can give a few examples:

I'm making an application with PHP at the moment where I have a model called users.php. Within this class I have methods working against the 'users' table, such as this:

/**
     * Runs the login credentials against the database
     * @param string - username
     * @param string - password
     * @return user_id / false
     * */
    public function verifyLogin($username, $password) {

        $password = $this->_hashPassword($password);

        $this->db->where('username', $username);
        $this->db->where('password', $password);
        $this->db->where('activated', 1);
        $this->db->where('deleted', 0);

        $query = $this->db->get(DB_PREFIX.'users');

        if ($query->num_rows() > 0) {
            $r = $query->result_array();
            return $r[0]['id']; // User ID
        }

    }

The model is loaded into the framework and I call this method from the controller like this:

$this->users->verifyLogin($_POST['login_username'], $_POST['login_password']);

The way I used to call it before was $this->users->verifyLogin();, letting the model simply take the $_POST variables and figuring it all out by itself. I just changed this as I would assume that controlling all input and output should go through the controller, virtually leaving the model 'actually fully encapsulated' even to me as the author of the code.

This shows the connection between my Controller and my Model, but what if I decided to use an independent library, say a Validation class I had made? Where would I implement this stand-alone class? Let's pretend this is a snippet of my application where I use my poorly designed validation class to give me an exception:

require_once('validator-class.php');

$val = new Validator($_POST['login_username']);

try {
$val->max_length(16)
    ->min_length(4)
    ->alpha_numeric();
}

Would I put this code into the controller or the model for best effect? If the model would be application-dependant, it would make most sense to delegate/call the methods of the library class from within the model and then very easily just call the model in a more simplified fashion such as a save() method where everything would be taken care of behind the scenes.

I've come to wonder if the controller is supposed to be used as a 'main area' for connecting the dots, being the place where I would call the methods of every class, delegate them to the model etc. while keeping the model 100 % outside-class-clean, only relying on itself solely and surely. But then again, if the model is supposed to be application-dependant, this would make little sense as I would not take the model with me to a new project and should instead just do all the calling and messy procedures within the encapsulated class.

I must apologize for the long explanation, but I struggle with even using the MVC pattern with this question in mind to the extent I'm seriously considering just letting go and moving back to the hard, pure PHP. Some help would be very appreciated. Also, a few tips on documenting class methods would be very welcome as a bonus.

Thanks a great deal!

share|improve this question
    
Uncle Bob talks about this problem a lot. The solution is a Clean Architecture, where your application is completely independent of frameworks and concepts such as MVC. Here, watch this keynote: youtube.com/watch?v=WpkDN78P884 –  MichelHenrich Apr 18 at 11:29

1 Answer 1

Would I put this code into the controller or the model for best effect?

Validation is part of your application domain and therefore should be located in your model. All functionality which is specific to the web interface, e.g. handling HTTP requests, cookies, session data, should be located in your controller or view.

Think of your model as the whole application without a user interface. You should be able to extend your application with an additional interface, e.g. web service, without changes (or only little changes) to the model. Also, all interfaces have to obey to the very same business rules, e.g. username may only consist of alphanumeric characters.

The way you changed your $this->users->verifyLogin($_POST['login_username'], $_POST['login_password']); method is the right way to go. By doing this the verifyLogin method does not depend on an HTTP POST request (with some specific parameter names) but instead can be used in various situations thus improving code quality, maintainability and separation of concerns.

To cite Wikipedia:

The model manages the behaviour and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.