请就以下创建模型层的方法提供反馈,该模型层由利用 Doctrine 进行数据访问的业务规则组成。
我目前的方法是基于这样一个概念,即模型是一个 ContainerAware 类/对象,所有非库、特定于业务的域逻辑都在其中。
我发现我必须锤击框架才能以这种方式做事,这就是为什么我的一部分大脑会质疑我的方法。
我目前正在使用 Symfony 2,它与所有现代 PHP MVC 框架一样,使用像 Doctrine 2 这样的 ORM 层,并且不可避免地将其视为模型层。我猜 ZF2 的情况会很相似,所以虽然我的例子是用 SF2 写的,但把这看作是一个与框架无关的问题。
具体例子
作为一个具体的例子,考虑以下场景:
消息要求
- 作为用户,我可以创建一个属于我的消息。
- 作为用户,我可以更新属于我的消息。
- 作为用户,我可以归档属于我的消息。
控制器
在 Symfony2 中,这些需求被编码为控制器层中的动作。 我将跳过检查消息是否确实属于用户的无关代码,但显然,这也应该是域逻辑的一部分。在“belongsToUser”或类似方法中。
// Vendor\MessageBundle\DefaultController
public function archiveAction(Request $request) {
// ...
$em = $this->getDoctrine()
->getManager();
$message = $em->getRepository('MessageBundle:Message');
->getManager()
->getRepository('MessageBundle:Message')
->find($request->get('id'));
$message->setIsArchived(true);
$em->persist($entity);
$em->flush();
$this->flashMessage('Message has been archived.');
// ...
}
该模型
如果我把它放到一个模型中,它看起来像下面这样:
class MessageModel
{
public function archive($messageId) {
// ...
$em = $this->getDoctrine()
->getManager();
$message = $em->getRepository('MessageBundle:Message')
->find($messageId);
$message->setIsArchived(true);
$em->persist($entity);
$em->flush();
// ... return true on success, false on fail.
}
}
修改后的控制器
我修改后的控制器现在看起来像这样:
// Vendor\MessageBundle\DefaultController
public function archiveAction(Request $request) {
// ...
$model = new MessageModel(); // or a factory.
$result = $model->archive($request->get('id'));
if($result) {
$this->flashMessage('Message has been archived.');
} else {
$this->flashMessage('Message could not be archived due to a system error.');
}
return array('result'=>$result);
// ...
}
其他两个要求也将在模型上实现。
简而言之我的方法
简而言之,这是我目前的方法:
- 控制器- 更少的逻辑
- 查看- 保持不变
- 模型- 容器感知并容纳所有业务逻辑,访问 Doctrine 作为数据访问。
- ORM - 被视为模型层的一部分,但不被视为模型层。
- 服务层- 需要时,我可以使用服务层来处理多个层,但我发现由于我必须构建的应用程序的简单性质,我只需要在少数情况下使用它.
我的问题
- 我的方法与其他人的做法一致吗?
- 我错过了一些明显的东西吗?
- 您是否尝试过类似的事情并发现它好/坏?
先感谢您。