Abd*_*el5 6 model-view-controller symfony
我正在使用symfony 2,我对代码分离有疑问.我想确保我正确理解控制器中应该包含哪些元素,服务中的内容以及实体中的内容.
让我们想象一下,我有需要显示的文档列表.在显示之前的每个文档上,我还必须执行一些逻辑操作(例如,添加两个变量).
理解实体类只关注单个实体上的数据检索和操作.我不应该输入任何自定义代码.据我所知,这应该由服务完成.
但我应该:
我宁愿认为第一种方法适合保持控制器薄(瘦控制器,大型模型),但这种方法是否合适?实体中应该有什么代码,控制器中有什么代码?服务中有什么代码?
特别是我应该在哪里与实体经理相关 - 在控制器中还是在服务中?
让我们假装在我的应用程序的许多地方我需要检查文档是否已完成,然后才允许用户执行任何操作(例如编辑它).这绝对应该是在服务中,因为需要另一个服务来检查这个.但是,我是否应该将文档实体对象加载到控制器中,将其发送到服务以验证它是否可以最终确定,或者更确切地说是在服务中加载文档并执行检查?
我的Symfony 2架构是(使用Doctrine ORM):
控制器内的每个动作都从实体的管理器调用一个或多个方法; 我总是试图避免直接使用存储库的"魔术方法"来支持自定义方法:在操作中,而不是调用
$this->getDoctrine()->getRepository(<entity>)->findBy(array('parent' => null));
Run Code Online (Sandbox Code Playgroud)
我在存储库中创建了这个方法:
public function findParents()
{
return $this->findBy(array('parent' => null));
}
Run Code Online (Sandbox Code Playgroud)
在我使用的动作中:
$this->getDoctrine()->getRepository(<entity>)->findParents();
Run Code Online (Sandbox Code Playgroud)
当然,这是一个简单的例子,但它适用于更复杂findBy或更复杂的findOneBy问题.
在Symfony2中,使用存储库和服务是超级简单的解耦逻辑.例如:
具有aditional自定义查找程序的实体存储库
use Doctrine\ORM\EntityRepository;
class MyEntityRepository extends EntityRepository
{
public function findAllWithX($parameter)
{
// your DQL. manipule own data. filters.
}
}
Run Code Online (Sandbox Code Playgroud)
处理主要业务逻辑的胖服务
// could be a listener
class MyFatService
{
public function __construct(MyEntityRepository $mer,
AnotherRepository $aor,
MisteriousService $mis)
{
$this->mer = $mer;
$this->aor = $aor;
$this->mis = $mis;
}
public function someBigAction($paramX, $paramY)
{
$foo = $this->mer->findAllWithX($paramX);
$bar = $this->aor->findBy(....);
// manipule data. complex operations.
// call related services.
// manipule data related to many repositories
}
}
Run Code Online (Sandbox Code Playgroud)
要定义服务:
services:
my_entity_repository:
class: AppBundle\Repository\MyEntityRepository
factory: [@doctrine, getRepository]
arguments:
- %entity.my_entity%
my_another_repository:
class: AppBundle\Repository\AnotherRepository
factory: [@doctrine, getRepository]
arguments:
- %entity.my_another_entity%
my_fat_service:
class: AppBundle\MyFatService
arguments:
- @my_entity_repository
- @my_another_repository
- @misterious_service
Run Code Online (Sandbox Code Playgroud)
在你的控制器中:
public function blaAction($x, $y)
{
// leave the heavy work to services.
// just handle request and send the response
$data = $this->get('my_fat_service')
->someBigAction($x, $y);
return $this->render('template.twig', ['data' => $data]);
}
Run Code Online (Sandbox Code Playgroud)
ps:对不起我的英语