我已经阅读了很多MVC文章,例如this site和this。我仍然不明白为什么控制器应该传递给视图类?
<?php
$model = new Model();
$controller = new Controller($model);
$view = new View($controller, $model);
if (isset($_GET['action']) && !empty($_GET['action'])) {
$controller->{$_GET['action']}();
}
echo $view->output();
什么时候我们可以在bootstrap或前端控制器中调用控制器动作然后是什么目的呢?
$view = new View($controller, $model);
答案 0 :(得分:2)
在宏设计层面,MVC是一个架构决策,表明开发中有三个概念必须分开。模型,视图和控制器。
为避免在SO上出现更多的“MVC理论”重复,这是一个非常被接受的答案,其中解释了MVC的基础知识:https://stackoverflow.com/a/5864000/1311025
您必须选择适合您的项目要求和变更视角的实施。
例如。如果我认为我的数据库将来会发生变化(我不知道什么时候,我只是怀疑它会改变)我会做一个绝对解耦我的数据库creating a layer that abstracts the implementation of it from the controller.的实现并实现一个提供的工厂您是访问数据库的正确实例。
如果我认为我的视图会发生变化,那么我将在视图中使用观察者模式来分离控制器和视图。通过事件,控制器和视图将进行通信。
然后,您可以按照满足您需求的软件设计模式构建自己的MVC实现。
现在,根据您提供的代码,
<?php
$model = new Model();
$controller = new Controller($model);
$view = new View($controller, $model);
if (isset($_GET['action']) && !empty($_GET['action'])) {
$controller->{$_GET['action']}();
}
echo $view->output();
思想是分离类(模型,视图和控制器)中的职责,对我来说,这是一个将视图与模型耦合的示例。但是,如果我们希望视图,控制器和模型将永远像这样并且永远不会改变,那就是正确的 此外,通过这种实现,控制器具有一个状态,反映出这种状态永远不会扩展(或者不是很容易)。
免责声明:这是我对简单,快速和小项目的实施。 如果您需要更严格的解决方案,那么质量不是一种选择, 那么你必须遵循更严格的指导方针。
在我看来,我会选择至少将视图与模型分离。
<?php
$controller = new Controller();
if (isset($_GET['action']) && !empty($_GET['action'])) {
$controller->doAction($_GET['action']);
}
控制器不必处理全局php变量($ _GET):
<?php
Controller {
public function __construct() {}
public function doAction($action) {
$model = new User();
$model->setName("user36279");
//This just transforms the user model in an associative array
$UserDTO = $model->toDTO();
$view = new UserView();
//We don't send the model to the view increasing decoupling
$view->render($UserDTO);
}
}
但这将是我的实施。现在您可以选择决定要分离多少,可维护性,复杂性和可测试性。
修改强>
有人指出:
[...]您的“控制器”实际上负责路由,检索 来自模型层的信息和响应的呈现,以及 当然违反了SRP和SoC。底线:所有这些都是 完全错了
他是对的,我的代码违反了SRP。但看看这个问题:
Does the traditional use of the controller in MVC lead to a violation of the Single Responsibility Principle?
如果您想关注SRP,则需要对Controller进行分解 进入Dispatcher和Actions; Dispatcher将控制权分派给 它的行动[...]
为什么我们不经常看到这个?因为控制器通常是“广告 特殊的“实现,叶级别的具体类,不是 概括的,并不意味着是子类。这里使用了这个类 更方便的是对代码进行分组,几乎可以肯定 非公开的(可能是私人的,也许是受保护的),“仅仅是”内部的 实施细节。
选择如何决定要发送的动作,数量和 可能的行动的多样性,高度,调度和行动 紧密耦合。 所以在实践中,通常更容易 代码集中在一个地方。
SOLID原则是设计面向对象的重要指南。这里的一般规则是承认不同的选择,并选择最适合您需求的选择。原则是指导而非规则,遵循这些原则的主要优点是一组与语言无关的通用解决方案,易于使用和理解新手和专家开发人员以及我们设计的简单性。
结论:当您需要应用SRP(单一责任原则)并因此实施SOLID时,由您决定。