2

是时候让我了解 MVC,这就是我想要做的;而且我很难理解模型应该做什么。根据Wikipedia,一个模型:

模型管理应用程序域的行为和数据,响应有关其状态信息的请求(通常来自视图),并响应更改状态的指令(通常来自控制器)。在事件驱动系统中,模型会在信息发生变化时通知观察者(通常是视图),以便他们做出反应。

在 CakePHP 中,您应该以这种非常简单的方式设置模型:

<?php

class Posts extends AppModel {
    var $name = 'Posts';
}

?>

因此,例如,如果我想要数据库中的最后 10 个帖子,我将创建一个如下所示的控制器:

<?php

class PostsController {
    function retrieve_latest($number = 10) {
        $posts = $this->Users->find(array(
                'fields' => '*',
                'order' => 'posts.post_id DESC',
                'limit' => $number,
                'page' => '1',
                'conditions' => array('posts.post_display == 1')
        ));

        $this->set('posts', $posts);
    }
}

?>

这个人会将一个名为的变量传递posts给我的视图,然后它会相应地渲染它。问题是,我的模型不应该做其他事情吗?因为如果它像这样简单,那么自定义模型根本没有意义,我的意思是,它只是模型类的一个空扩展。

4

3 回答 3

5

这个“对模型类的空扩展”已经做了很多事情:它连接到数据库并完成检索和保存数据的所有分钟处理。它应该做更多的事情,包括保存在您写入数据库时​​强制执行的验证规则、过滤器之前/之后所需的任何数据按摩以及您在应用程序中需要的任何其他自定义业务逻辑。模型用于存储您的中央业务数据逻辑,因此任何与表示或输入/输出无关但本质上为应用程序的核心逻辑建模的东西。仅仅因为基础设置很简单并不意味着它们没有更多内容。

于 2011-11-14T01:31:30.540 回答
4

模型还封装业务逻辑并处理彼此之间的交互。例如,如果一个帖子有评论,那将在模型中处理。您不希望控制器获取帖子然后获取评论并组装它们。这会将了解模型结构的责任放在控制器上,它不属于它。

事实上,在许多应用程序中,模型不包含太多逻辑(如果有的话)。一个只有数据字段而没有业务逻辑的模型可以被认为是一个 DTO(数据传输对象)或只是一个“对象”,因为它不“建模”任何类型的业务逻辑。这不一定是坏事,这取决于需求。许多应用程序都是简单的表单数据应用程序,不需要任何额外的逻辑。

但是,如果您的应用程序具有的逻辑不仅仅是任何给定表中的数据,那么该逻辑就会出现在模型中。他们不仅对数据进行建模,而且对领域进行建模。事实上,模型不直接具有相同的数据库结构的情况并不少见。模型是面向对象的,而数据库更常见的是关系型。这两者并不总是以相同的方式解决问题。如果您的模型需要精确复制您的表,那么您将限制自己使用更多面向对象的功能。

简而言之,任何解释业务所做的事情都会进入模型。控制器只是事件处理程序,响应用户界面请求。控制器通常是为手头的应用程序定制的,而模型应该可以跨多个应用程序重用,因为它们代表了业务逻辑的核心。

于 2011-11-14T01:34:06.297 回答
1

以您的示例为例,理想的是瘦控制器和胖模型。这意味着您的代码应该理想地重构为以下内容:

class Post extends AppModel {
    var $name = 'Post';

    function retrieveLatest($limit = 10) {

        return $this->find('all', array(
            'order'=>'Post.id'=>'DESC',
            'limit'=>$limit
        );

    }

}


class PostsController extends AppController {

    function retrieve_latest($limit) {

      $posts = $this->Post->retrieveLatest($limit);

      $this->set(compact('posts'));

    }

}

您的控制器不应该关心获取最新信息所必需的复杂细节,即业务逻辑并进入模型,靠近数据。另一个好处是您还可以从任何相关模型中检索最新帖子:

$posts = $this->User->Post->retrieveLatest();

您甚至可以更进一步,将 retrieveLatest() 代码移动到您的 AppModel 中,以便每个模型都继承它:

class AppModel extends Model {

    function retrieveLatest($limit = 10) {

        $model = $this->alias;

        return $this->find('all', array(
            'limit'=>$limit,
            'order'=>array(
                $model . ".id"=>'DESC'
            )
        );

    }    

}

根据经验,每当您发现自己在控制器中构建查询时,将它们移动到模型中并给它们起一个描述性的名称。

于 2011-11-14T16:50:13.913 回答