エリック・エヴァンスのドメイン駆動設計 4章メモ
3章の週は時間が取れなかったので一旦飛ばしました。
4章はドメインを表現する箇所と技術的な要求を実現する箇所を分離すべき理由とその方法としてのレイヤ化アーキテクチャについて。
4章 ドメインを隔離する
- (ravelll)ドメインから生じる問題とは?
- あるドメインにおいてソフトウェアが解決したい問題?
- 問題解決の流れを表現する部分と技術的な流れを実現している部分が混ざらないようにする必要がある
- そうしないと何がモデルなのかをソフトウェアから理解することが難しくなる
レイヤ化アーキテクチャ(LAYERED ARCHITECTURE)
- (ravelll)"ビジネスロジックとは何?"という問いに対する答えを1つ言語化できるようになる章っぽい
- MVC の例
- UI の変更がビジネスロジックの変更を巻き込んでしまう
- "凝集度の高いモデル駆動のオブジェクトを実装することが現実的ではなくなる"
- ビジネスモデルを純度高く反映したオブジェクトを実装するのが難しくなるということ?
- 技術的なフローを実現するコードとビジネスモデルを表すコードが混ざるとテストもぎこちなくなる
- Layered Architecture で関心事を分離しつつ相互作用も継続してできるようにする
- "本質的な原則は、レイヤ内のどの要素も、同じレイヤの他の要素か、その「下にある」レイヤの要素にしか依存しない、ということである。"
- "レイヤの価値は、それぞれがコンピュータプログラムにおける特定の側面を専門的に扱うことにある。"
- "もちろん、決定的に重要なのは、設計における最も重要で凝集度の高い側面を隔離するレイヤを選び出すことだ。"
- Layered Architecture は具体的な層の設計までを提供するものではなさそう
- とは言えうまく行っているところはだいたいこういうパターンになるよね、という傾向はある
- それぞれのレイヤはそれぞれ異なる速度で進化する
- 各レイヤーは分散して配置されうる
- 表示、格納、アプリケーションタスク管理などのロジックはドメインモデルの表現には不要
- "アプリケーションタスク管理" とは?
- (ravelll)依存が単方向になるべき理由を言語化できる?
- 双方向になる => 互いに互いを知ることになる => 関心事を一方に留めておけなくなる ということ?
オンラインバンキングの機能をレイヤに分割する
- ドメイン層でやるのは (1) 指定された口座Aを振込元して口座Bに対して指定された金額を追加すること (2) 指定された口座Aから指定された金額を引くこと
- トランザクションを開始・コミットする、振り込みを DB に記録する、等はスコープ外
- "おそらくそこには、元帳オブジェクトや、振り込みおよび引き落としオブジェクト、金銭取引オブジェクトなどが含まれていただろう。"
- 振る舞いもオブジェクトなんだ。オブジェクトとは…?
レイヤを関係づける
- 依存方向を逆転したいときはコールバックやオブザーバーを使う
- (ravelll)アプリケーションコーディネータとは?
アーキテクチャフレームワーク
- "多くのインフラストラクチャの要求を統合するフレームワークを使うと、他のレイヤをきわめて特殊な仕方で実装しなければならなくなることも多い。"
- Rails の話か???
- "最もよくできたアーキテクチャフレームワークは、複雑な技術的問題を解決する一方で、ドメイン開発者がモデルを表現することに集中できるようにする。しかし、フレームワークは、ドメインについての設計の選択肢を制限する前提を多く設けすぎたり、開発の速度を低下させるほど実装を重苦しくしてしまったりすることで、容易に開発の妨げとなり得るのだ。"
- (ravelll)ドメインオブジェクトってつまるところ何?
- ドメインモデルのいずれかの登場人物に対応するクラス?
- フレームワークを選ぶときはちゃんとソフトウェアがモデル駆動となるものを選びましょう
ドメイン層はモデルが息づく場所
- ドメイン駆動設計におけるレイヤ化アーキテクチャ => ドメイン層があること
- "利口なUI(Smart UI)"
- "同じ理由から、モデル駆動設計に取り組むチームは、最初からそれにふさわしいやり方で設計する必要がある。(snip)しかし、最初の一歩を試しに踏み出す先が、ドメインレイヤを隔離したモデル駆動でなければ、プロジェクトは利口なUIに行き詰まることになるだろう。"
- この章ではドメインを隔離して実装する方法として Layered Architecture を紹介しているが、ドメイン層をどのようにやっていくかについては後続の章が担当するっぽい