レイヤードアーキテクチャとは
シンプルなアーキテクチャです。
あまり評価が高くない
「ソフトウェアアーキテクチャの基礎」では最初に紹介される、基本的なアーキテクチャですが、「コスト」と「シンプルさ」以外の評価は低いです。
評価が高くない理由
自分も実感としてレイヤーを増やすのは意味がなく、「Djangoのようなフルスタックフレームワークを使っているなら、まずそのフレームワークに備わっている機能を最大限活かすのが近道」と書きました。
1. まずドメインで区切るべき
コードの保守性を高めるためにまずやるべきことは、ドメインで区切ることです。 Djangoなら「アプリケーション」という単位で区切ることができます。技術的にはPythonのモジュールです。 そしてPythonのモジュール間の依存関係を一方向にすることで、保守しやすいコードになります。
また、最近のチームは「機能横断型チーム」です。すなわち、レイヤーを跨って1つの機能を作り上げるチームです。 なのでレイヤーで分けるのではなく、ドメインで分けた方が小さなチームにできます。
2. レイヤーを増やす目的が不明瞭
レイヤーを増やす目的は本来、下層レイヤーを取り替えられることです。 例えばデータベースのインタフェースを抽象化すれば、データベースを取り替えることができます。
しかし実際、データベースを取り替える必要があるでしょうか。 PostgreSQL←→MySQLレベルなら、ORMで抽象化されています。 例えば最初はRDBMSで作って、それからNoSQLにしたいのであればレイヤーを増やす意味はあります。 しかし単に「綺麗なコード」を実現するためにはレイヤーを作る必要はありません。 DDDでも「サービス」はありますが、あくまで「ドメインサービス」です。レイヤーではありません。
3. linterで対応しないとレイヤーが安定しない
まずレイヤードアーキテクチャを有効的にするためには、レイヤー間が片方に依存することを強制する必要があります。 例えばMVCの場合、Viewはテンプレート言語という制限された環境、Controllerがまず処理を受け取る立場ということで、処理が逆転することはありません。 例えばFat View, Fat Controllerのように正しくない形になることはありますが。
しかし、レイヤーを増やすとその強制がうまくいかなくなります。 linterで対応できたらいいのですが、もし相互参照してしまうと、レイヤーを増やすことは逆効果になります。
結論
結論としては、まずドメインで分離して、それから必要に応じてレイヤーでの分離を試みることです。 実際のところ、レイヤーで分離するよりは、CQRS、CommandとQueryで分割した方が分かりやすいかもしれません。