【发布时间】:2012-07-16 09:47:55
【问题描述】:
在阅读了很多帖子和 Stack Overflow 资源之后,我仍然对“将业务逻辑放在哪里?”这个著名的问题有些疑问。看了StackOverflow Question和A Blog Post,相信我已经很好地理解了代码分离的问题了。
假设我有一个 Web 表单,您可以在其中添加将被添加到数据库的用户。这个例子涉及到这些概念:
- 表格
- 控制器
- 实体
- 服务
- 存储库
如果我没有遗漏什么,您必须创建一个具有一些属性、getter、setter 等的实体,以使其持久保存到数据库中。如果您想获取或写入该实体,您将使用entityManager,对于“非规范”查询,使用entityRepository(您可以在其中使用“查询语言”查询)。
现在您必须为所有业务逻辑定义一个服务(即带有“惰性”实例的 PHP 类);这是放置“重”代码的地方。将服务记录到应用程序中后,您几乎可以在任何地方使用它,这涉及代码重用等。
当您呈现和发布表单时,您将它与您的实体绑定(当然还有约束),并使用上面定义的所有概念将所有内容组合在一起。
所以,“old-me”会这样写控制器的动作:
public function indexAction(Request $request)
{
$modified = False;
if($request->getMethod() == 'POST'){ // submit, so have to modify data
$em = $this->getDoctrine()->getEntityManager();
$parameters = $request->request->get('User'); //form retriving
$id = $parameters['id'];
$user = $em->getRepository('SestanteUserBundle:User')->find($id);
$form = $this->createForm(new UserType(), $user);
$form->bindRequest($request);
$em->flush();
$modified = True;
}
$users = $this->getDoctrine()->getEntityManager()->getRepository('SestanteUserBundle:User')->findAll();
return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));
}
“New-me”以这种方式重构了代码:
public function indexAction(Request $request)
{
$um = $this->get('user_manager');
$modified = False;
if($request->getMethod() == 'POST'){ // submit, so have to modify data
$user = $um->getUserById($request,False);
$form = $this->createForm(new UserType(), $user);
$form->bindRequest($request);
$um->flushAll();
$modified = True;
}
$users = $um->showAllUser();
return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));
}
$um 是一个自定义服务,其中存储了从 #1 代码段到 #2 代码段您看不到的所有代码。
所以,这是我的问题:
- 我终于掌握了 symfony2 和 {M}VC 的精髓了吗?
- 重构是好的吗?如果没有,有什么更好的方法?
Post Scriptum:我知道我可以使用 FOSUserBundle 进行用户存储和身份验证,但这是一个自学如何使用 Symfony 的基本示例。 此外,为了工作,我的服务被注入了 ORM.Doctrine.* (只是为谁读过这个问题而感到困惑)
【问题讨论】:
-
$modified 的作用是什么,getUserById() 的第二个参数的作用是什么?
-
好吧,领域业务逻辑进入model layer。莫斯利在domain objects。
-
@redbirdo :问题的目的无关紧要。
-
@tereško :所以我正在“走好路”。我已经阅读了您的答案,并且发现某些点完全符合我上面的描述(实体:域对象和验证器、服务:作用于该域对象和数据映射器(即存储库和实体管理器))
-
@DonCallisto 我认为 getUserById() 的第二个参数确实很重要,因为我试图了解您的 UserManager 是否具有定义明确的接口(在“重构是否良好”的上下文中) .至少我建议您避免将 $request 对象暴露给您的 UserManager,因为它是一个 UI 构造。最好从 $request 中提取 id 并将其传递给 UserManager。
标签: model-view-controller symfony