多くの投稿やスタック オーバーフローのリソースを読んだ後でも、「ビジネス ロジックをどこに置くべきか?」という有名な質問について、まだいくつか問題があります。StackOverflow QuestionとA Blog Postを読んで、コード分離の問題をよく理解できたと思います。
データベースに追加されるユーザーを追加できる Web フォームがあるとします。この例には、次の概念が含まれます。
- 形
- コントローラ
- 実在物
- サービス
- リポジトリ
私が何かを見逃していなければ、データベースに永続化するために、いくつかのプロパティ、ゲッター、セッターなどを持つエンティティを作成する必要があります。そのエンティティをフェッチまたは書き込みたい場合はentityManager
、「非正規」クエリに and を使用します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.* が注入されました (同じ混乱でこの質問を読んだ人へのメモです)。