我创建了一个简单的ServiceFactory类,它运行其他Service类,存储和获取实例。 View对象和Controller对象之间共享相同的ServiceFactory对象。
Controller更改服务的状态:
class User extends Controller
{
public function index($user)
{
$userService = $this->service->run('User');
$userService->index($user);
}
}
View从服务获取数据并决定使用哪个模板:
class User extends View
{
public function index()
{
$userService = $this->service->get('User');
$this->data = $userService->data;
$this->template = 'user/index'; // render
}
}
我是否正确地做到了?
在this中,回答tereško说:“控制器负责改变视图和模型的状态。”我的控制器与视图无关。我想看一些Controller和View应该如何工作的例子(Model2 MVC)。
答案 0 :(得分:2)
我做得对吗?
排序。
让我们从extends
开始。当您使用extends
时,您意味着 is-a 关系,所以当您说User
延伸Controller
时,您就说了User
是-a Controller
。是这样的吗?不。也许您可以重命名为UserController
,这样会更有意义。
$userService = $this->service->get('User');
这称为service locator,它以反模式而众所周知。 为什么是一种反模式?因为在面向对象的编程中,每个对象的公共方法都是其使用的API,并且您应该能够完全从它的构造函数和方法签名中看到对象需求。
使用您的代码,开发人员必须仔细阅读整个内容以查看"哦,所以我在这里使用其他对象"并且进一步向下"在这里,我使用另一个"。
您的代码 应如下所示:
public function index(UserService $userService)
{
$user = $userService->getData();
}
通过代码更改,开发人员可以看到对象需要运行的外部对象 - 现在这是可测试的(并不是说您将测试不包含逻辑的控制器 - 他们只是'胶水& #39;对于已经过测试的代码。)
您应该将组件和视图注入控制器:
class UserController extends Controller
{
public function index(UserService $userService, View $view)
{
/** This or something similar **/
return $view->render($userService->getData());
}
}
有些人注入了View
,有些人注入TemplateEngine
像树枝,并用数据调用render
。它取决于您,您可以根据当前情况深入研究具体细节。
如果您想知道如何将您的用户服务注入索引操作,那就是使用反射的依赖注入器Auryn的工作读取对象构造函数或方法签名,以确定在控制器中自动注入之前要创建的内容。
Laravel窃取了这个想法,现在已经为他们的控制器实现了这一点,希望Symfony能够很快跟进。
结束说明:不要试图严格遵守MVC' - 对于带有请求的PHP,它在经典意义上是不可能的 - >回应 - >死循环。相反,要专注于与之相关的问题的分离,并使您的代码可维护,可测试且易于阅读。
答案 1 :(得分:0)
在客户端 - 服务器架构中,实现MVC的“原始”思想存在问题。理论上,控制器应该修改模型。比模型更应该被喜欢视图更新它的事件。
实施例: 我改变了用户的状态,例如单击某个按钮的名字。这导致控制器中的动作更新用户模型(生活在模型层中的域模型)。现在模型应该“改变”视图以更新用户的名字。您可以使用“commet”-architecture(https://en.wikipedia.org/wiki/Comet_%28programming%29)将Model链接到View。因此,用户模型的更新将会更新视图。