クリーンアーキテクチャ、こうしたら現実的かも
クリーンアーキテクチャ、現実のWebアプリにそのまま適用するのは無理じゃないですか? コントローラの扱いが微妙で、クラスが多すぎな気がします。
現実的な解をぼくなりに考えたところ、上図の構成になりました。原典との違いは3点です。
- コントローラをいちばん外に移動した
- インタラクタの入力/出力ポートをなくした
- プレゼンタもなくした
これが正しいというつもりはなく、疑問点などフィードバックをいただけたらありがたいです。
以下、原典との違いとその意図です。
コントローラをいちばん外に移動した
クリーンアーキテクチャ原典の図では、フレームワークがいちばん外(水色の層)、コントローラがその内側(緑色の層)に置かれています。
その構成のまま、クリーンアーキテクチャの「依存性のルール」(ソースコードの依存性は内側にだけ向かっていなければならない)を厳守するには、コントローラがフレームワークを直接参照できません。
しかし、一般的なWebアプリケーションフレームワークを使う場合、コントローラはフレームワークを直接参照せざるをえません。フレームワーク固有のリクエストオブジェクトを解釈したり、フレームワーク固有のテンプレートエンジンを呼び出したりしなければならないからです。
結局、コントローラはフレームワークと同じか、より外側に置かれるのが妥当だと思います。なので、いちばん外に移動しました。
インタラクタの入力/出力ポートをなくした
原典の書籍版は、内側のユースケースから外側のプレゼンタを呼び出すと想定しています(第22章 クリーンアーキテクチャ「境界線を越える」)。
その上で、依存性のルールを守るには、プレゼンタがユースケースの出力ポートインターフェイスを実装し、ユースケースがそのインターフェイスを呼び出さなければならないといいます。
しかし、ユースケースからプレゼンタを呼び出す必要があるのでしょうか。コントローラがユースケースの出力を受け取り、プレゼンタに渡すだけで、用が足りると思います。
入力ポートもそうです。ユースケースからコントローラを呼び出す必要はなく、ユースケースで使う値をコントローラが直接渡せば充分だと思います。
入力も出力も、コントローラとユースケースとの直接的なやりとりで充分なら、ポートはいらないはずです。ということで、入力ポートと出力ポートをなくしました。
プレゼンタもなくした
プレゼンタの責務は、インタラクタが返す値のフォーマットです。書籍では、Dateオブジェクトや、Currencyオブジェクトを、適切な文字列にフォーマットする例が紹介されています(第23章 プレゼンターとHumble Object「プレゼンターとビュー」)。
が、フォーマット程度であれば、ビューテンプレートのタグに任せてよいのではないでしょうか。便利な機能があるのに、使わないのはもったいない気がします。
フォーマット済み文字列のテストは、テンプレートエンジンの返すHTMLを対象とすれば可能です。むしろ、テンプレートエンジンに渡す前の値をテストしているプロジェクトのほうが珍しいのではないでしょうか。
ということで、プレゼンタもなくしました。
まとめ
現実のWebアプリをクリーンアーキテクチャにするためのアレンジ案をご紹介しました。疑問点、不明点など、フィードバック大歓迎です。ではまた。