-
Notifications
You must be signed in to change notification settings - Fork 33
WIP: [best practice] controllers.rst翻訳中 #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
コントローラー | ||
=========== | ||
Symfonyは薄いコントローラとファットなモデルという哲学に従います。 つまり、コントローラは、 | ||
アプリケーションの様々な部分をとりまとめるグルーコードだけからなる薄いレイヤーにするべきです。 | ||
|
||
経験則として、正確な基準はありませんが、コントローラに定義する変数は5個以下、 | ||
アクションの数が10個以下で、各アクション内の行数は20行以内という「5-10-20ルール」に従う事は | ||
コードをコントローラからサービスにリファクタリングする際に役に立ちます。 | ||
|
||
.. best-practice:: | ||
|
||
開発者がコントローラを作る場合``FrameworkBundle``のコントローラを継承し、 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ここは主語なしで「コントローラーを作る場合〜」とすると良いと思います。 |
||
可能な限り、ルーティング、キャッシュとセキュリティをアノテーションで設定してください。 | ||
|
||
|
||
コントローラとフレームワークを連携させることで、フレームワークの機能すべてを | ||
活用する事を可能にし、あなたの生産性を向上させます。 | ||
|
||
そして、コントローラーは薄く、数行のグルーコードであるべきで、 | ||
フレームワークからそれらを切り離すそうとすると、時間かかるので長期的に見ると利益になりません。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
大量の時間を費やすだけで、何の価値もありません。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
翻訳してみると「消費された時間(の量)は何の価値もありません」でしょうか。
|
||
|
||
加えて、 ルーティング、キャッシュ、セキュリティに対してアノテーションを使用すると簡単に設定する事ができます。 | ||
すべての設定は必要な場所に一つのフォーマットにすれば、YAML, XML, PHPなどの複数ファイルを見る必要がなくなります。 | ||
|
||
全体的にビジネスロジックをフレームワークから切り離すという手段は積極的に行うと | ||
同時に、最大限に活用にするためにルーティングとコントローラは結合するべきです。 | ||
|
||
ルーティング設定 | ||
--------------------- | ||
|
||
コントローラで定義されたアノテーションを利用するにはrouting.ymlに以下の設定を追加します。 | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/routing.yml | ||
app: | ||
resource: "@AppBundle/Controller/" | ||
type: annotation | ||
|
||
``src/AppBundle/Controller/`` ディレクトリとそのサブディレクトリからコントローラの | ||
アノテーションをロードします。 | ||
もしアプリケーションに多くのコントローラがある場合、それらをサブディレクトリへ移動する事が可能です。 | ||
|
||
.. code-block:: text | ||
|
||
<your-project>/ | ||
├─ ... | ||
└─ src/ | ||
└─ AppBundle/ | ||
├─ ... | ||
└─ Controller/ | ||
├─ DefaultController.php | ||
├─ ... | ||
├─ Api/ | ||
│ ├─ ... | ||
│ └─ ... | ||
└─ Backend/ | ||
├─ ... | ||
└─ ... | ||
|
||
テンプレート設定 | ||
---------------------- | ||
|
||
.. best-practice:: | ||
|
||
テンプレートの設定は ``@Template()`` アノテーションを使用しないでください。 | ||
|
||
``@Template``は便利ですがいくつかの魔法を伴うので、お勧めする事はできません。 | ||
|
||
ほとんどの場合、``@Template``はパラメータの設定をせず使用されます。そして設定すると、どの | ||
テンプレートを表示するかをわかりづらくします。それはまた、必ずコントローラはレスポンスオブジェクトを | ||
返すべきだと言う事を初心者にわかりにくくしてしまいます。(あなたがビューレイヤーを利用している場合以外) | ||
|
||
最後に、@Templateアノテーションはkernel.viewイベントのイベントディスパッチのフックとして | ||
TemplateListenerクラスで利用されます。そのリスナーのパフォーマンスへの影響を紹介します。 | ||
ブログのサンプルアプリケーションのホームページをレンダリングする場合、$this->render()メソッドを | ||
使った場合5ミリ秒かかり、@Templateアノテーションを使った場合26ミリ秒かかりました。 | ||
|
||
How the Controller Looks | ||
------------------------ | ||
|
||
Considering all this, here is an example of how the controller should look | ||
for the homepage of our app: | ||
|
||
.. code-block:: php | ||
|
||
namespace AppBundle\Controller; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
|
||
class DefaultController extends Controller | ||
{ | ||
/** | ||
* @Route("/", name="homepage") | ||
*/ | ||
public function indexAction() | ||
{ | ||
$em = $this->getDoctrine()->getManager(); | ||
$posts = $em->getRepository('App:Post')->findLatest(); | ||
|
||
return $this->render('default/index.html.twig', array( | ||
'posts' => $posts | ||
)); | ||
} | ||
} | ||
|
||
.. _best-practices-paramconverter: | ||
|
||
ParamConverterを使う | ||
------------------------ | ||
|
||
もしDoctrineを使っている場合は必要に応じて`ParamConverter`_ を使い、自動的にエンティティを取得し、 | ||
コントローラの引数として渡す必要があります。 | ||
|
||
.. best-practice:: | ||
|
||
シンプルかつ簡単な場合は、自動的にDoctrineのエンティティを取得出来るParamConverterを使用 | ||
してください。 | ||
|
||
例: | ||
|
||
.. code-block:: php | ||
|
||
/** | ||
* @Route("/{id}", name="admin_post_show") | ||
*/ | ||
public function showAction(Post $post) | ||
{ | ||
$deleteForm = $this->createDeleteForm($post); | ||
|
||
return $this->render('admin/post/show.html.twig', array( | ||
'post' => $post, | ||
'delete_form' => $deleteForm->createView(), | ||
)); | ||
} | ||
|
||
通常は ``showAction`` では ``$id`` という変数を引数として使うと思います。 | ||
代わりに ``$post`` 引数と ``Post`` クラス(Doctrineのエンティティ)をタイプヒンティングする | ||
ことによって、そのオブジェクトを自動的にParamConverterが``{id}`` の値と一致する | ||
``$id`` プロパティのものを取得します。``Post`` が見つからなかった場合は404ページが表示されます。 | ||
|
||
高度な事 | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This works without any configuration | ||
This works without any configuration because the wildcard name ``{id}`` matches | ||
the name of the property on the entity. If this isn't true, or if you have | ||
even more complex logic, the easiest thing to do is just query for the entity | ||
manually. In our application, we have this situation in ``CommentController``: | ||
|
||
.. code-block:: php | ||
|
||
/** | ||
* @Route("/comment/{postSlug}/new", name = "comment_new") | ||
*/ | ||
public function newAction(Request $request, $postSlug) | ||
{ | ||
$post = $this->getDoctrine() | ||
->getRepository('AppBundle:Post') | ||
->findOneBy(array('slug' => $postSlug)); | ||
|
||
if (!$post) { | ||
throw $this->createNotFoundException(); | ||
} | ||
|
||
// ... | ||
} | ||
|
||
You can also use the ``@ParamConverter`` configuration, which is infinitely | ||
flexible: | ||
|
||
.. code-block:: php | ||
|
||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
|
||
/** | ||
* @Route("/comment/{postSlug}/new", name = "comment_new") | ||
* @ParamConverter("post", options={"mapping": {"postSlug": "slug"}}) | ||
*/ | ||
public function newAction(Request $request, Post $post) | ||
{ | ||
// ... | ||
} | ||
|
||
The point is this: the ParamConverter shortcut is great for simple situations. | ||
But you shouldn't forget that querying for entities directly is still very | ||
easy. | ||
|
||
Pre and Post Hooks | ||
------------------ | ||
|
||
If you need to execute some code before or after the execution of your controllers, | ||
you can use the EventDispatcher component to `set up before/after filters`_. | ||
|
||
.. _`ParamConverter`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html | ||
.. _`set up before/after filters`: http://symfony.com/doc/current/cookbook/event_dispatcher/before_after_filters.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは文章が長くなるので一度切るとよいのではないかと思いました。実際英文も切れていますし。
`経験則ですが、コントローラに定義する変数は5個、
アクションの数は10個、各アクションの行数は20行以下にするという「5-10-20ルール」に従うのがよいでしょう。
正確な基準というわけではありませんが、ルールに従うことでコントローラーからサービスにリファクタリングすべきタイミング(時)が分かるでしょう。
but it should help you realise~
→ あたたが気づくのを助ける → 気がつける (分かる)という感じかと。
@hidenorigoto ここの英語の解釈これで合ってますでしょうか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
概ね間違っていないと思いますが、前の文からの流れも踏まえてブラッシュアップ(意訳)するとしたら
「この数字に科学的な根拠はありませんが、コントローラーからサービスへリファクタリングすべきタイミングを見極める基準としては役立ちます。」