前回のふりかえり
第15章 蒸留
- 蒸留は、モデルから副次的なものを切り落とし、本当に重要なもの(コアドメイン)に焦点を当てやすくする
第16章 大規模な構造
境界づけられたコンテキストや蒸留などの方法を取れば、モジュール自体の役割やモジュール間の相互作用については表すことができるが、システム全体の構成は表現できない。「木を見て森を見ず」では全体像が見えず、継続的な統合が崩壊してしまうので、開発者が全体像を見えるようにしてやる必要がある。
→ それが 大規模な構造
- 大規模な構造 は、システムをおおよその構造から議論し、理解できるようにするための言語
- さまざまな部分の果たす役割が、どのように全体を構成するかについて概念を共有するためのもの
[留意点]
- ルールについてのパターンや、役割や関係性についてのパターンを考え出す
- パターンがあることで、全体における各部分の位置づけが、その部分の責務を詳細に知らなくても理解できるようになる
これ以降は、このレベル(大規模なレベル?)での設計をうまく構造化するためのパターンが紹介される
進化する秩序
- 設計が構造化されていないと、開発者は全体像を捉えられず保守も困難になる
- 一方で、アーキテクチャの制約が強すぎると、開発者の自由を奪ってしまう
→ 大規模な構造を一度に設計するのは不可能。アプリケーションと共に進化させ、場合によっては途中で全然違う構造に変えることもある。
[留意点]
- 設計とモデルに関する意思決定を制約させるような構造になってはいけない
- 大規模な構造は必須ではない。導入が効果的なのは、費用対効果が良く、うまく整合する構造が見つかった時(誤った構造を作ってしまうくらいなら構造自体無い方がよい)
大規模な構造の一般的なパターン
システムのメタファ
- ソフトウェアの設計は、非常に抽象的で把握しにくい傾向がある。
- システムを理解して、全体としてのシステムの見方を共有するための具体的な方法は、開発者もユーザーも等しく必要としている
→ そのような課題を解決するのに、メタファは効果的
- メタファを使うことで、チームメンバーのシステムへの理解を促すことに役立つのなら、それを大規模な構造として採用する
- メタファを中心に設計して、ユビキタス言語に取り入れる
- ただし、メタファは不正確なものなので、それが適切なのか常に検討し、不適切であれば取り消す必要がある
責務のレイヤ
(これが本当に難しかった。まだあんまりよくわかってない)
- 巨大なモデルに一貫性を与えるには、それぞれのオブジェクトに責務を与える際に、何らかの構造を課すことが有効。
- ドメインによっては自然な階層を形成するものもあり、そのようなドメインにはレイヤ化が適している。
[レイヤの特徴]
- 上位のレイヤは下位のレイヤと知っている
- 下位のレイヤは上位のレイヤのことを知らない
→ モジュールと集約に割り当てる責務をグループ化して名前をつけると、責務を元にレイヤ化することができる
知識レベル
- エンティティ間のある役割と関係が状況によって変化するシステムでは、複雑さが爆発的に増えかねない
- そのような状況では、カスタマイズされたモデルも・汎用的なモデルも要求には応えられない
→ 知識レベルは、モデルを構造化する。そのようなモデルの自己定義的な側面と分離して、制約を明示的にする
- ソフトウェアを二つの側面に分け、知識レベルでモデルの構造とふるまいを記述することで、制約を明示的にすることができる
- アプリケーションの業務に関する責務を持つ「ベース(業務)レベル」
- ソフトウェアの構造とふるまいに関する知識を表す「メタ(知識)レベル」
更に成熟した大規模な構造のパターン
着脱可能コンポーネントのフレームワーク
深められ、蒸留されて非常に成熟したモデルがブレークスルーを迎えることで、着脱可能コンポーネントのフレームワークパターンに達する
- インターフェースや相互作用にある抽象化されたコアを蒸留し、そのインターフェースの多様な実装を自由に置換できるようにするフレームワークを作成する
- 抽象化されたコアのインターフェースを経由して操作する限り、全てのアプリケーションがこのコンポーネントを使用できるようにする
- 適用するのが非常に難しい
- インターフェースは正確に設計する必要があるし、そのために深いモデルが必要
- アプリケーションの選択肢が限られている
- 抽象化されたコアの変更が非常に難しいため
※着脱可能コンポーネントのフレームワークを成功させるには、ドメインに対するかなりの理解が必要。最初から取り組もうとするものではない
思ったこと・気になったこと
ついに次章で最後...