理解MVC:模型上的"胖"概念是什么,控制器上的"瘦"是什么?

pun*_*bit 21 php model-view-controller paradigms

我试图理解模型上的"胖"和控制器上的"瘦"的概念以及我一直在讨论的内容我有以下示例(这是从freenode讨论中获得的):

问:关于MVC范例,它说Fat模型,瘦的控制器.我在这里想,如果我有很多方法(在控制器上)只使用一些抽象方法到CRUD(在模型上),我是在创建一个胖控制器而不是模型?或者他们说,胖模型,在返回和不打字的内容中进行补偿?这是我从未理解的东西=)任何评论都表示赞赏!非常感谢

OBS1:我没有在模型中做什么,在控制器中,我只有控制最新模型的方法

OBS2:让我们说"checkIfEmailExists()",有"john@hotmail.com"作为参数.这个方法将从模型方法返回,如果这个param存在于表中,则返回boolean.如果是0,"checkIFemailExists()"将调用一个不同的模型方法,这个,他只是另一个抽象方法,执行更新操作.

OBS3:"checkIfEmailExists()",不只是一个控制器?他实际上并没有执行任何CRUD,他只是在比较数值等等.这让我感到困惑,因为在我脑海中这是一个控制器:S

注意:我想这不是最好的例子,因为说"检查是否存在某些东西",听起来像是一个查询我的表操作

Q2:还有一个问题,所以,假设我有一个视图表单,从那里发送该电子邮件地址参数.你是说这个观点直接与模型有关吗?

问题3:控制器不应该在他们之间行动吗?这就是范例

最后注意:讨论结束了,说我错了,希望没问题(我正在学习).但是,那么,Q2和Q3的正确答案是什么?

谢谢你的关注

Gor*_*don 34

您的应用程序是M.它应该能够独立于V和C. V和C构成您的应用程序的用户界面.无论是Web界面还是命令行界面,运行应用程序的核心业务逻辑都无关紧要.您希望模型具有业务逻辑.

如果您有一个胖控制器,例如完全具有业务逻辑,那么您就不会遵循MVC的目的.控制器的唯一责任是处理和委托UI请求到模型.这就是为什么它应该是瘦的.它应该只包含它负责的代码.

简化示例

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $bar = Sanitizer::sanitize($_POST['bar']);
        $rows = $this->database->query('SELECT * from table');
        try {
            foreach($rows as $row) {
                $row->foo = $bar;
                $row->save();
            }
        } catch (Exception $e) {
            $this->render('errorPage');
            exit;
        }
        $this->render('successPage');
    } else {
        $this->render('fooPage');
    }
}
Run Code Online (Sandbox Code Playgroud)

什么时候应该

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $success = $this->tableGateway->updateFoo($_GET['bar']);
        $page    = $success ? 'successPage' : 'errorPage';
        $this->render($page);
    } else {
        $this->render('fooPage');
    }
}
Run Code Online (Sandbox Code Playgroud)

因为这是所有控制器需要知道的.它不应该更新行.它应该告诉模型有人要求这种改变.更新是管理行的类的责任.此外,控制器不一定要清理该值.

至于Q2和Q3,请参阅我的回答我可以从视图中调用模型.

  • 说得好!保持业务逻辑不受控制器的影响. (2认同)
  • @Lykos差不多.您的模型不仅仅是数据库.这是您的整个应用程序减去用户界面.您的模型将包含数据访问*和*处理逻辑.表单验证是UI的一个方面,但不应直接进入控制器,而应进入专用的验证类(因此您可以重用它们).您可以在控制器中使用它们.重定向不是UI而是传输层,例如,当您使用HTTP时,它将适合某种类型的Response对象.控制器真的只是一个委托人. (2认同)

Mat*_*sca 8

我已经和MVC范例合作了很长时间,我可以和你分享我的经验.

"模型"部分负责处理所有非严格"网络"的内容,例如验证,逻辑,数据访问等.将其视为一种混合业务层+数据访问层.您还可以在单​​独的程序集中使用BLL + DAL,并使用MVC的"Model"部分作为BLL和App之间的桥梁,并添加特定于MVC应用程序且与BLL无关的类,例如ViewData类等

"控制器"部分负责处理特定于Web的内容,例如身份验证,Cookie,GET和POST,查询字符串等.它使用模型和/或BLL中存在的内容并发送必须呈现的数据给用户的意见.

"视图"是您的html模板,可以从控制器接收数据并显示它.在视图中不应该进行任何逻辑操作,因此没有"if"语句,没有循环等.如果你发现自己有这样的需求,那么你需要一些"帮助"方法来创建所需的html,然后从中调用它们.视图.因此,视图只接收数据,并向用户提供链接/表单以将数据发布到控制器,但它们没有详细说明任何内容.

希望这清除了你的一些疑虑.

  • 这很好,但是我不同意观点,他们不应该缺少所有逻辑,需要显示逻辑.通常,为了从视图中删除所有逻辑,人们最终会创建太多的部分视图,或者更糟糕的是,他们将"视图"数据(例如HTML或XML)添加到控制器或辅助方法中.看待它的一个更好的方法是你应该只将形成的数据传递给视图,除了显示它之外,不应该对它进行进一步的操作,如果显示数据需要循环,那么就这样吧. (3认同)