dougou1943 2014-12-09 22:18
浏览 10

MVC模型应该是静态的吗?

EDIT: After some research, I saw this framework: this MVC framework. It have classes in Libs folder which are static (like Config, Session), can I use these ?


I am pretty new to MVC practices, and I am stuck on a weird problem..

I have many models, such as DB, User, Config, etc.. but I'm using many of these in each function I create.

I have a problem working with MVC patterns; I created multiple models, I'm using each one of them to handle grouped tasks(connection, DB, ect..).

Problem is, after creating the basic models, I ended up with code like this(within the controller).

class User
{
    function signup($username, $password, ...) 
    {
        $config = new Config();
        $DB       = new DB();
        $HTML     = new Session();
        // And so on...

        $canRegister = $config->get("registration-enabled");
        if ($canRegister and ..) {
            $this->username = $username;
            $DB->saveAccount($this);
            $session->setUser($this);
        } else {
            throw new Exception('bad signup');
        }
    }
}

I have to create instances of many models just for one or two functions.. but if the models are static, it should look like this:

class User
{
    function signup($username, $password, ...) 
    {
        $canRegister = Config::get("registration-enabled");
        if ($canRegister and ..) {
            $this->username = $username;
            DB::saveAccount($this);
            session::setUser($this);
        } else {
            throw new Exception('bad signup');
        }
    }
}

Note that many models doesn't use __construct method.. so is it good practice (or not bad) to have statics models in a MVC pattern ?

Please see EDIT above before responding.

  • 写回答

1条回答 默认 最新

  • duanluo9369 2014-12-10 11:38
    关注

    Model is a concept of abstraction!

    Model consist of services, while services themselves consist of storage abstractions and objects that handle computations. Simply put, a service is a bridge between domain objects and storage abstractions (such as Data Mappers or Table Gateways). A model consists of those services.

    That's a typical way how a model should be structured:

      Model
        - Storage
           - MySQL
              - YourMapper
        - Service
           - YourService
    

    A class that handles abstraction to a table and does computation and validation is also known Anemic Model (which seems to be your case), because it violates the SRP and breaks Separation of Concerns.

    When adhering to this right way, you can easily replace storage (say you can replace MySQL to MongoDB) since they no longer tightly-coupled to business logic. Or you can replace domain objects that handle computations without even touching a storage.

    And no, nothing ever should be static!

    For the purpose of example, let's imagine, that your write a library that does file uploading.

    class Uploader
    {
         ... 
    
         public function upload(array $files)
         {
             $path = Config::read('upload_path');
             $some_another_option = Config::read('foo');
    
             $this->move($path, $some_another_option, $files);
         }
    
         ...
    }
    

    So what kind of problem might lie here? Just remember that we write a library, and let's face these facts:

    • In order to use a uploading library, the Config object must be properly instantiated and its data must be fully loaded into the memory. Which is a waste of RAM and

    • What if you decide to replace Config to another source of required information? You can't because its tightly-coupled

    • If you want to distribute your library, you will also have to distribute your Config + its dependencies, which will make your library look bad.

    Yeah, you probably have seen this approach in another frameworks. But popular doesn't mean correct, anyway.

    The right way,

    You gotta remember that object instantiation is another responsibility too. When you instantiate a Conifg you probably load data from somewhere (array or a table, whatever). So in your first approach you gotta load it n-times? That's seems a very wrong way to do.

    What you should really do is to instantiate Config only once, and pass it to classes the require it, like this:

    $config = new Conifg();
    $config->load(__DIR__ . '/config_array.php');
    
    
    $user = new User($config);
    
    $system = new System($config);
    
    // and so on, you got the point
    

    The same applies to your DB and Session. Classes which use these objects should not bother about their instantiation. They just gotta bother how to use them.

    Remember: Nothing ever kills code reuse-ability like Static classes and Singletons

    All cool dudes refer to this technique as Dependency Injection

    评论

报告相同问题?