了解MVC:模型上的“脂肪”,控制器上的“瘦子”是什么概念?

2022-08-30 19:00:52

我试图理解模型上的“脂肪”和控制器上的“瘦”的概念,从我一直在讨论的内容中,我有以下示例(这取自freenode讨论):

问:关于MVC范式,它说胖模型,瘦控制器。我在这里想,如果我有很多方法(在控制器上)只使用几个抽象方法来CRUD(在模型上),我是否创建了一个胖控制器而不是模型?或者他们说,胖模型,在返回和不键入的内容中重新引用?这是我从未理解过的东西=)任何评论都值得赞赏!多谢

OBS1:我不是在做模型所做的事情,在控制器中,我只是有控制模型内容的方法。

OBS2:假设“checkIfEmailExists()”,有“john@hotmail.com”作为参数。此方法将从查询此参数的模型方法获取返回,返回布尔值。如果为 0,“checkIFemailExists()”将调用一个不同的模型方法,这个,他只是另一个抽象方法,执行更新操作。

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

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

Q2:还有一个问题,假设我有一个视图表单,从中发送该电子邮件地址参数。你是说视图直接进入模型吗?

Q3:控制器不应该在它们之间行动吗?这就是范式

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

感谢您的关注


答案 1

您的应用程序是 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');
    }
}

什么时候应该

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

因为这就是控制器需要知道的全部内容。它不应更新行。它应该只是告诉模型有人请求此更改。更新是管理行的类的责任。此外,控制器不一定必须清理该值。

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


答案 2

我已经使用MVC范式很长一段时间了,我可以与您分享我的经验。

“模型”部分负责处理所有不是严格“web”的东西,例如验证,逻辑,数据访问等。可以把它想象成一种混合业务层+数据访问层。你还可以将 BLL+DAL 放在单独的程序集中,并使用 MVC 的“模型”部分作为 BLL 和应用之间的桥梁,以及添加特定于 MVC 应用且与 BLL 无关的类,如 ViewData 类等。

“控制器”部分负责处理Web特定的东西,例如身份验证,Cookie,GET和POST,查询字符串等。它使用模型和/或 BLL 中存在的内容,并将必须呈现给用户的数据发送到视图。

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

希望这能消除你的一些疑虑。


推荐