ADRパターン実践時のトレードオフとの向き合い方
こんにちは、ナカエです。
少し前になりますが、4月のlaravel.osakaにてADR(Action-Domain-Responder)パターンについてのLTをさせていただきました。
ADRパターンというと1Action=1クラスという特徴に注目する方が多いですが、一番の見所はResponderですよ! Webアプリケーションの"ビュー"についを考え直しましょうという趣旨のものです。
- スライド: "ビュー"を考えるためのADRパターン
- GitHub: n1215/lara-adr ADRパターン on Laravelで同じDomainの処理をコンソールコマンド、Web API、Webページの3通りに使い回すサンプルコードです
スライドはほぼ理念の説明とメリットに終始したので、ADRパターン実践時の感想とトレードオフについて補足しておきます。
ADRパターンのデメリット
実際にADRパターンを試してみると、利点も多くありましたが、
- Actionのファイルに1つ1つコンストラクタ注入を書くのがだるい
- 複数のActionでメソッドを共有するときControllerでprivateメソッドのような楽ができない
- Responderクラスをいちいち作るのが面倒
- 処理がController以外に分散して一覧性が悪い
と感じました。同じような感想を抱く方は多いと思われます。
プログラミングは間接層の導入に伴う利便性とコストのトレードオフをどちらに倒すかという選択の連続です。ADRパターンにも、小クラス主義が故の保守性と実装の手間のトレードオフがあります。
目先のコード記述量の少なさを至上命題とするならば、初めの感触はよくないかもしれません。
もし新しいプロジェクトにADRを全面採用するのであれば、利用するフレームワークのベースの上にADRに寄り添うような改造を施すべきでしょう。
ADRのために設計されたWebフレームワークの力を借りるのも一手です。
たとえば、RadarPHPはADRのActionとRresponderのボイラープレートにかかる手間を吸収し、Domainの部分により注力できるようにした素晴らしいフレームワークです。
ADRとMVC2の間
ならば一般的なMVCフレームワークを使った既存のプロジェクトでADRパターンを実践することはできないでしょうか?
いえ、ADRパターンのエッセンスの一部はすぐにでも十分実用できます。
Controllerが神へと至るのを防ぐ
Actionクラスは、Actionメソッドを一つしか持たないControllerクラスとみなすことができます。
要はHTTPリクエストを引数にしてHTTPレスポンスを返すメソッド群をどうグルーピングしどう共通化するか、という問題への回答のうち最も極端な1つがADRパターンで推奨されているにすぎません。
特に1つのリソースに対して多機能だったり複雑な処理を行うアプリケーションを実装しようとする際はよく考えてみてください。CRUDにこだわらず、Actionメソッドが1つしかない、もしくは少ないControllerクラスをもっと気軽に作ってみましょう。
ControllerクラスのままでResponderの導入
HTTP MiddlewareやControllerに置いて、HTTPレスポンスを生成するコードが何回も出てきてDRYにならないとき、Responderを使ってコードの重複を防ぐこともできます。
個人的にはエラー発生時のHTTPレスポンスを生成するのに重宝しています。
まとめ
ADRには一般的に利用されているMVCに対してメリットデメリットがあり、全てのプロジェクトで全面採用すべきものではないでしょう。ですが、その一部を使うだけでも十分に恩恵を得ることができます。