Upload
mao-ohnishi
View
3.111
Download
0
Embed Size (px)
Citation preview
アジェンダ• 言葉の定義
• ドメイン駆動設計の原則
• 効果的なモデリングの要素
• 戦略的設計
• より深いドメインモデルへ向かうリファクタリング
• しなやかな設計
• ドメインの隔離方法
• まとめ
ドメインとは?• ドメインとは、ソフトウェアを利用する人達の活動と関心ごと。
• ソフトウェアの利用は利用者の活動の一部なので、利用しないシーンも含めて活動の目的・背景を理解することがドメインを理解するということ。
ドメインに集中する• 一番複雑なのは、『ドメインそのもの(ユーザの活動やビジネス)』
• ドメインの複雑性を考慮して、設計すべき。
• 技術だけに注力して作られたソフトウェアはドメインエキスパートの考え方と結びつかない。
• 業務中心 > 技術中心
ドメインモデルを探求する• ドメインに対する深い理解と集中すべき主要な概念を反映したモデルを作成する。
• ドメインエキスパートと開発者の共同作業でドメインモデルを作り上げていく。
• ドメインモデルは時間と共に進化する。
ユビキタス言語を語る• ユビキタス言語により、ドメインエキスパートと開発者を結びつける。
• ドメインモデルを作成するための共同作業は、ドメインエキスパートと開発者で共通認識の言語を形成していくプロセス。
• ユビキタス言語はコードやタスク・機能の記述などでも利用
・ドメインモデルがプロジェクトの中心で、 他のドキュメントなどはモデルから言葉を取り出す
“ドメインモデルに基づいて
言語を洗練させる”
・最終的には、プロジェクトで流れ続ける情報を 体系化するためのツールとしてモデルを位置付ける
・データモデルと違い、振る舞いと業務ルールも表現する
“知識豊富なドメインモデルを作成”
・ドメインエキスパートの頭にある膨大な情報から 役に立つ知識をモデル化する
・開発メンバーが全員参加で作成する
・分析と設計の両方で利用できるモデルを作成
・会話の表現がわかりやすいか、ぎこちないかを検証する
“ドメインモデルの言葉をブレーンストーミングなどで実験する”
・メンバ全員で一緒にモデルをかみ砕くことにより、 メンバ間のやりとりを変化させていく
境界づけられたコンテキスト• 明示的に境界づけられたコンテキストを定義した上で、ドメインモデルを適用するのはコンテキスト内部に限定。
• コンテキスト同士の関係も定義することによって、モデルの質が低下するのを避ける。(コンテキストマップのこと)
蒸留• モデルで最も価値がある領域をコアドメインという。
• コアドメインを探す活動を蒸留という。
• コアドメインを見つけて、コアドメインをサポートする大量のモデルやコードから容易に区別する手段を提供すること
大規模な構造 ~責務のレイヤー~
• ドメインモデル内にある概念上の依存関係を調べて、自然な階層が認められたら、階層に抽象的な責務を割り当てを実施。
• 階層は、ドメインの基本的な現実や優先事項を伝える。
• 階層の責務を決める際は、技術的な意思決定というより、ビジネス上の意思決定で行う。
戦略的設計のまとめ• 「大規模な構造」と「蒸留」によって、ドメイン内の複雑な関係を理解できるようになる一方で、全体像を見失わずにいられる。
• 「境界づけられたコンテキスト」によって、別々のシステムの作業を進めても、モデルを壊してしまったり、意図せず断片化してしまったりすることがなくなる。
リファクタリングのアプローチ• ドメインリファクタリングから開始。
• ドメインモデルのリファクタリングにおいて、ドメインモデルに対する不満の原因が何であれ、意図を明確かつ自然に伝達するようモデルを改良する方法を探し出す。
コミュニケーションのぎこちなさ• コミュニケーションのぎこちなさに敏感になることによって、リファクタリングの候補を探す。
• ドメインエキスパートと開発者の両方ともドメインモデルにない語彙を使用したら警告サイン。
• 警告サインを好機と捉えて、その語彙を取り込むことでドメインモデルとコードを改善する。
設計のぎこちなさ• 以下のような複雑な箇所は、ドメイン側の活動における目的や背景を改めて理解して、改善につなげる。
• 新しい要求が来るたびに複雑になっていく箇所
• 説明しにくい複雑な業務ロジックが存在する箇所
リファクタリングの最終目標• コードが何をしているかを理解できるようになることに加えて、コードで表現された背景を理解できるようになること。
• これにより、ドメインエキスパートとのコミュニケーションとコードが関連づき、より深いドメインモデルを探求できる。
大切なこと• ドメインモデルと実装は、絶えず前進するだけのプロセスではない。
• 初期のドメインモデルと実装では重要と思えなかった問題が、困ったことになるのを防ぐために、頻繁にリファクタリングを行い、ドメインモデルと実装を改善するプロセスが大事。
テクニックの分類抽象化
理解を容易にして、 詳細を隠蔽する
分割
適切な粒度を保ち かつ依存関係を排除する
意図の明白な インターフェース
副作用のない関数
表明
概念の輪郭
独立したクラス
閉じた操作
意図の明白なインターフェース• クラス名/メソッド名は手段ではなく、目的が把握できるユビキタス言語の名前を付与。
• ユビキタス言語にすることによって、チームメンバーがすぐに意味を推測できる。
• 呼び出し側はインターフェースの内部処理を理解不要。
副作用のない関数• 複雑なロジックは、副作用のない関数によって、安全に実行。
• 副作用とは、システムの状態に対して行われる、あらゆる変更を意味。
• 呼び出し側で、副作用があるのか/ないのかを安全に予測できることが重要。
• コマンドクエリ分離の考え方。
表明• システムの状態を変更するメソッドは、表明によって特徴づける。
• 表明の具体的な表現方法としては、自動化されたユニットテストで表現。
条件名 説明
事後条件• 事後条件が操作の副作用なので、メソッドを呼び出すことで保証される結果を記述
事前条件 • 事前条件とは事後条件が成り立つことを保証するために満たすべき条件
クラスの不変条件• あらゆる操作が終わったときのオブジェクトの状態を宣言。集約全体の整合性に関するルールを厳密に定義
概念の輪郭• ドメインオブジェクトは、意味のある単位をより直感的に使用したり、組み合わせたりできるような単位で分割。
• 最初から理想となる分割はできず、リファクタリングした結果によるもの。
✦ リファクタリングは技術視点ではなく、ドメイン視点で実施。
閉じた操作• 引数の型と戻り値の型が同じ場合は、閉じた操作と呼ぶ。
• 閉じた操作にすることによって、引数と戻り値が同じ型になるので、余計な概念を呼び込む必要がなくなる。
• 操作の引数や戻り値に新たなクラスが登場すると、新たな依存関係ができてしまう。
隔離手段 ~レイヤ化アーキテクチャ~
• ドメイン駆動設計では以下4層に分離。
レイヤー名 説明ユーザインターフェース層 • ユーザに情報を表示して、ユーザからの何らかのリクエストを解釈
アプリケーション層• ビジネスルールや知識は含まない • やるべき作業を調整するだけで、実際の処理はドメイン層に委譲 • ビジネス状況を反映する状態は保持しない
ドメイン層• ビジネスの概念やビジネスルールを表現 • ビジネス状況を反映する状態はドメイン層で制御され、実際の格納処理はインフラストラクチャに委譲
インフラストラクチャ層• ドメインオブジェクトの永続化処理を行う • アプリケーションのためのメッセージ送信
隔離する目的• 本質的なビジネスの知識を捉えることが可能。
• プロジェクトが進むごとに蒸留しやすい設計。
• ソフトウェアの技術(htmlやsqlなど)に関係する概念と混同しなくなるので、ドメインを見失うことを避ける。