「ValueObjectという考え方」でDDDの片鱗について書かせていただきました
今回はDDD本のなかでも少し抽象度の高い「レイヤードアーキテクチャ」について深堀っていきます
レイヤードアーキテクチャとは
レイヤーアーキテクチャ・レイヤードアーキテクチャと呼ばれているこのアーキテクチャ指向です
DDDは特定技術へ依存しているわけではないのでDDD=レイヤードアーキテクチャ!とならないように気をつけましょう
上位互換の思想として以下のものがあります
- ヘキサゴナルアーキテクチャ
- オニオンアーキテクチャ
- クリーンアーキテクチャ
基本的にどのアーキテクチャも一貫して責務を適切に設定して依存関係を明確にするという目的があります
一番原始的(?)なレイヤードアーキテクチャはその名の通り
責務を適切に設定した塊=層(レイヤー)をイメージします
これだけじゃなんのことやらって感じですね
更に技術っぽい責務を割り振って依存の方向を一方方向にします
これがレイヤードアーキテクチャの基本的なイメージ図です
DDD本内ではもっとユビキタスな表現を使って以下のような層を定義しています
- UI層
- Application層
- Domain層
- Infrastructure層
UI層
表示における関心事を取り扱う層です
Webアプリケーションで扱うhttp requestやquery paramといった「表示に関するテクノロジー」はこの層から漏れ出ないようにします
また、ドメインの情報を書き換えるといった操作はすべてApplication層を介して行い、直接ドメインオブジェクトに影響を与える操作はUI層で行わないようにします
Application層
ユースケース毎にドメインオブジェクトのコーディネートの関心事を取り扱う層です
UI層からのリクエストに対してCRUD・ELTを行う層とも言えます
依存関係からUI層のテクノロジーを認知しなくてもいいように実装されます
また、ドメインの情報を書き換えるといった直接的な操作はドメインオブジェクトの振る舞いを介して行い、直接ドメインオブジェクトの値を変える操作はApplication層で行わないようにします
DBなどの永続化への影響のある操作も行いません
Domain層
ビジネスルール・仕様の関心事を取り扱う層です
ここでようやくユースケースやユーザストーリーといったビジネスモデルの表現を行います
ドメインの情報を書き換えるといった直接的な操作を行います
UI層やApplication層の実装・テクノロジーを知らなくてもいいように実装されます
Infrastructure層
永続化テクノロジーの関心事を取り扱う層です
DB、メモリ操作といったテクノロジーに関する実装をこの層にまとめます
また、ドメインオブジェクトに対してデータをパースしたりマッピングを行うこともします
他の3層の実装を知らなくてもいいように実装されます
レイヤードアーキテクチャの利点
ここまで見ているとなんだか複雑かつルールがややこしいように見えるだけですが
大きな利点は関心事の分離にあります
仮にUI層にスポットを当てて考えましょう
例) Webアプリを作っていたあるプロダクト が Nativeアプリを作ろうとする
大変そうですね
しかし、レイヤードアーキテクチャを採用・実践できていれば追加実装はUI層にとどまります
更に永続化で使用しているDBを変更したい事案が発生!
例) MySqlとPostgre両方で使用したい!
変更箇所は明確ですね
コードの影響を調査する手間も減ります
(まぁ、現実問題は開発言語の問題やらetc... でココまでうまくいかないですが…)
このように層で整理されているので変更に対して強く、影響をイメージしやすくなります
レイヤードアーキテクチャの弱点
上記で利点を述べましたが弱点もあります
- ストアドチックなコードより記述量は増える
- チーム開発で共通認識を作るのが大変
- ドメインロジックがテクノロジーの変更により影響を受ける
ストアドチックなコードより記述量は増える
将来に渡り変更が軽微な場合や検証段階ではオーバーテクノロジーになりますね
用法用量を守る必要があるのはアーキテクチャ採用の常なので意識する必要があります
チーム開発で共通認識を作るのが大変
習熟度により差が生まれるのは設計・チーム開発のツラミでもあります…
頑張って共通認識をつけるしかないですね(ぇ
ドメインロジックがテクノロジーの変更により影響を受ける
依存方向を見ると明らかですね
これは**依存性の注入(DI)**を利用することで解消できます
DIについての詳細はまた別の機会に
いかがでしたか?アーキテクチャを意識していなかった方が興味を持つきっかけになれば幸いです
実践できれば長期的に良い影響があり、ビジネス的な課題に寄り添っていけると思います
その他
軽量DDDでもやったほうがいい理由、けどやらない理由
ValueObjectという考え方
Serviceクラスの意義と勘所
集約で境界を正しく表現する意味