DDDを具体的なプロセスに落とし込むにはどういう観点が必要だろうか。 - 境界づけられたコンテキストがどこまでの範囲かよくわからない - ユビキタス言語やドメインモデルをどのように発見すればいいかわからない。どこから着手すればいいのか? - ドメインモデルがただのデータの入れ物になってしまう(貧血症) という問いに答えるには、RDRA, ICONIXを検討するとよいというテーマの資料です。
DDD with RDRA, ICONIXJunichi Kato (@j5ik2o)
View Slide
自己紹介● Scala歴 6年● サーバサイド開発・設計担当● 最近やってること○ OAuth2周り
アジェンダ● Scalaでの実装技法は誰かがしゃべってくれるので、今日は「分析/設計」についてフォーカスする。ということでScalaの話はでてきません:P● DDDを具体的な開発プロセスに落とし込むにはどうしたらよいのか?● DDDを知らなくても開発プロセス論として聞いてもらってもよいです
クネビンフレームワーク● Simple(単純)○ 因果関係はすべて明白。「知覚 - 分類 -対応」アプローチ。ベストプラクティスの適用● Complicated(煩雑)○ 因果関係の把握には分析もしくは何らかの調査、専門的知識が必要。「知覚 - 分析- 対応」アプローチ。適切なプラクティスの適用● Complex(複雑)○ 因果関係の把握は振り返りによってのみ可能であり、事前には不可能。「探査 - 知覚 - 対応」アプローチ。プラクティスの出現。● Chaotic(カオス)○ システムレベルでの因果関係が存在しない。「行動 - 知覚 - 対応」アプローチ。新たなプラクティスの発見。ソフトウェア開発はこちらの傾向が強い以降のスライドは、複雑な要件に対するアプローチです
DDDを実践する際の課題● 実際の開発プロセスに落とし込むにはどうしたらよいかわからない。○ 境界づけられたコンテキストがどこまでの範囲かよくわからない○ ユビキタス言語やドメインモデルをどのように発見すればいいかわからない。どこから着手すればいいのか?○ ドメインモデルがただのデータの入れ物になってしまう(貧血症)● 分析麻痺(完璧な分析→実装に進めない)ではなく、十分に分析せずに実装するということになってないでしょうか?(仮説)
● リレーションシップ要件駆動分析(RDRA)● ユーケース駆動開発(ICONIX)● ユーザーストーリーマッピング(USM)● 組織パターン● マイクロサービス役に立つ開発手法を提唱している書籍今日のスコープはここ。すべてを取り上げることはできないので、興味があれば本を読んでみてください。
注意事項:すべてのプラクティスを適用すればよいということではなく、観点を得ることが重要。鵜呑みにせずに考えてみてください。
RDRAとは網羅的で整合性のある要件定義をUMLの表現力を使って、要件定義としてまとめる手法をリレーションシップ駆動要件分析(RDRA)という。
RDRAの基本コンセプト● 網羅性○ コンテキスト、システムの外部環境を捉え、システムが使われる範囲を明らかする。そこからシステム要件を求めることで網羅的に要件をまとめる。● 整合性(今回紹介しないので興味があれば書籍を読んでください)○ システムの外部環境からシステムの要件までを複数の視点からモデルとして表現する。各モデルの情報を関係づけることで、情報の整合性を保つ。● 表現力○ 様々な視点から対象を表現することで多様な要求を構造的に表現する。それを図的な表現としてUMLを使って表現する。それにより議論しながらドキュメントを作成する。
要件定義の基本的な考え方● システム価値○ システムと関係を持つ対象とそこからの要求を捉える● システム外部環境○ システムを取り巻く外部環境を明らかにする● システム境界○ システムの外部と内部の境界線を明らかにし、システムの範囲を明確にする● システム○ システム内部の機能とデータ構造を明らかにするシステム(システムそのもの)システム価値(システムを使って生み出す価値)システム外部環境(システムを取り巻く環境 )システム境界(システムとの接点 )4つの価値は強い依存関係があり、システムを語るには、これらの要素は不可欠となる。
要件定義のための4つの領域システムシステム価値システム外部環境システム境界 ドメインモデルドメインモデルドメインモデル外部システムイベントユースケース情報情報業務フロー/利用シーン
RDRAのモデルを利用する● 関係者と合意を取りながら「どのようなシステムを構築するのか」ということを分析し、明確にシステムのイメージに落とし込むことが重要。● その際に必要となるのは、アイデアの表現手段としてのモデル(RDRAのモデル)。モデルを通じて現状把握→共通認識→議論→合意形成というプロセスを踏むことができる。あたり前のように聞こえるが、あなたの常識がチームの常識とは限らない。RDRAは認識齟齬を埋めるための形式的手法です。
ドキュメント作成=要件定義ではない● 要件定義は、ドキュメントを作成することを目的としない。対象を分析・定義することでシステムの要件を固めていく作業。ドキュメントはその知識を共有するために利用する手段。● 以下の2点の観点が必要。○ システムが対象とする利用シーンの範囲○ 段階的にシステム要件につなげる道筋
イベント告知サイトの例
システム価値システムと関係を持つ利害関係者や外部システム、およびシステムに対する要求を洗い出す
コンテキストモデル● システムへの要求を発生させる元となる利害関係者・外部システムを洗い出すためにコンテキストモデルを作成する。開発時と運用時の両面で考える。図を分けてもよい。● このシステムに対して要望・要求を持つと考えられる、経営者は間接的なつながりを示す。● アクターはヒアリング対象。後のプロセスで、役割・責務を明確にしていく。アクターの種類が多い場合は汎化を検討する。
要求モデル● 各アクターが持っている、機能要求・非機能要求を洗い出す● 要望→要求→要件○ 要望: こうできたらいいなという思いつきレベル○ 要求: 検討対象として合意されているもの○ 要件: 開発対象として合意されているもの● 開発者は機能に関心が向かいがち。機能の根源となる要求を整理することは整合性の取れたシステムを作るために必要● USMでいうところのバックボーンの洗い出し
システム外部環境システムを取り巻く外部環境として、業務フロー・利用シーン、および関連する概念をモデル化する
利用シーン● 汎用的に利用されるツールやサービスなどの提供を目的にする場合は、利用シーンを利害関係者別に整理する(特定の業務が対象であれば、業務フロー)。● システムがどのような場面で利用され、どのような価値を生み出すかを捉える。● USMのバックボーンに相当
概念モデル● 対象となる業務でどんな用語や概念が使われているか整理する。● 合意形成するには、共通の概念が欠如していては不可能。同じ用語でも文脈が違えば、目的が変わる可能性があります。中古車販売会社と自動車修理工場では、「車」に対するとらえ方が変わるなど。議論がかみ合わない場合は、まず概念の整理が必要。● ICONIXでも補強できる
システム境界システム内部と外部の境界に位置するものとして、ユースケース、画面・帳票、プロトコル・イベントなどを明らかにする
ユースケースモデル● システム化する範囲はどこまでか。システムとの接点はどのようになるのかを明確にする● それを明確にするため、ユースケースモデルを作成する。ユースケースを人間とシステムとの対話に関する範囲に限定する。● 洗い出しにはUSM, 分析にはICONIXでの補強をお勧めします
画面/帳票モデル● 画面・帳票が種類や主要な項目などを洗い出す。ユースケースと紐付いてなければならない。● (所見)ホワイトボードのラフなスケッチやペーパープロトタイプでもよい気がする。
プロトコル/イベントモデル● 外部システムからのイベントや、外部システムとのインターフェイスを洗い出しルール化する。● 外部システムとの連携は、人間が相手ではないので、状態マシン図を使用してモデル化できる。● データのライフサイクルや条件によって有効・無効になる機能がある場合はこの手法で整理する。● ここでいう状態とは外部システムと当該システムの両方、相互作用を表したものになる。
システム最後にシステムの内部構造を明らかにする。データモデルもしくはドメインモデル、機能モデル、ビジネスルールを作成する
ドメインモデル● システム化対象領域の概念(知識)をソフトウェア構造にマッピングし、その概念構造をシステム上に再現することが目的● システムに対する要求や変更はビジネス上の概念から発生するので、その概念がシステム上に存在することでシステムが理解しやすくなる● 右図のようなドメインモデルには最初から到達しない。ブレストの中で違和感を排除しながら、合意形成する必要がある。● ICONIX, Eric本での補強をお勧めする
機能モデル● 機能がどのユースケース、画面・帳票、イベント、ドメインイベント関係するかを表したモデル。
ICONIXとはRUP, XPなどのアジャイルソフトウェア開発よりも前から存在するソフトウェア開発方法論の一つ。UMLのユースケース駆動だが、RUPより軽量。以下の4つのマイルストーンがある● 要求定義○ 要求レビュー● 分析/概念設計/テクニカルアーキテクチャ○ 予備設計レビュー● 設計/コーディング○ 詳細設計レビュー● テスト/要求の追跡○ 配置
要求定義● 要求レビューまでにやること● まず、ドメインモデルから洗い出す○ 多重度などは意識せず用語からドメインモデル候補を探索して図にする。ただし不完全なものと仮定している● なぜユースケースが先ではないのか、ユースケースはドメインモデルの用語を使って記述されるべきだから。モデルの静的な部分と動的な部分を結びつけることができる。● 要求が明らかになっていればこの手法でよいが、不明瞭であればRDRAのシステム価値に基づき、利害関係者と外部システムを洗い出し、要望を要求として蒸留した方がよいと考える。
ドメインモデリング● 考えられる用語を列挙。ほとんどが同じ概念を指す言葉として使われている。そのままシステム化すると混乱のもと。用語を洗い出しながら排除する○ モデルとしてのユーザとユーザアカウントの違いは?ユーザアカウントはエンティティだが、ユーザはアクターです。○ グループリストとコミュニティリストは、同じものなのでどちらかに決める。コミュニティリストに決定○ イベントの検索キーワードはUI要素。責務が異なるのでそんなことはやめましょう。タグと命名する。● 用語リストから、最初のドメインモデル(静的)を作る。○ 集約(has-a), 汎化(is-a)のみの表現。属性・振る舞い、多重度はこの段階では早すぎる。分析が終わってからにしましょう。不完全と仮定し、分析麻痺を回避する用語リスト初期のドメインモデルを作る
ドメインモデルを発見する● チームでブレストを行うと、新たなドメインモデルを発見することもある。● 無料はもちろん、有料の場合はクレジットカードで決済できるようにしたい→ では、イベントプランと、ユーザアカウントにはクレジットカードというドメインモデルが必要!● まだ、曖昧なところがたくさん!ドメインモデルを精査するには、声に出してみること。”ユーザアカウントはクレジットカードを持っている”。それに、違和感がなければ役に立つモデルである静的な側面しか扱っていないことに注意!
ドメインモデルを探求する● 次のブレストで、主催者アカウントと参加者アカウントは、独立して検索されるエンティティ(集約)だろうか。あれ、なにかがおかしい!● そのイベントの主催者や参加者が誰かということだけに関心がある。現状のままだと、イベントを手に入れても誰が主催者か参加者かわからない。これは分析と設計を分離したモデルでは!あれ、コミュニティがないとイベントが作れないか、独立に作れるのかわからない。あいまい!● 最終的に、is-aではなくhas-aを利用した以下のモデルにたどり着いた
ユースケースモデリング● ICONIXでは、ユースケースによってシステムが駆動する。つまり、ユースケースが設計駆動することを意識する。実際には、全ユースケースに対して、シーケンス図を起こすことになる。● ユースケースをドメインオブジェクトに紐付ける。ユースケース駆動のオブジェクト指向設計を実現する(RDRAの機能モデルと同様)● ドメインモデルの名前を使って、ユースケース図を書く。● 洗い出したユースケースの規模が大きい場合グルーピングする。図をきれいにするコストは掛けてはならない。ユースケースの依存関係も整理していく。アクター・ユースケース・ドメインモデルつながりを網羅することが重要
● 肝心なのはユースケースの内容=ユースケース記述○ 「動詞+れる/られる」などの、指示的な記述をしてはならない。○ 叙述(じょじゅつ)的な記述にすること。● 指示的な記述○ 「ユーザは、ユーザ名とパスワードを使った認証方式でログインできる」● 叙述的な記述○ 「ユーザは ユーザ名とパスワードを入力して、「 ログイン」ボタン をクリックする。システムはユーザ名からユーザの情報を取り出し、パスワードをチェックする。そして、ユーザはシステムにログインする」● 述べるのではなく示す○ 述べるだけだと、ソフトウェアの重要な振る舞いが隠されてしまう○ 述べるのではなく、ログインに含まれる手順を示すことが重要。叙述的なユースケースを書く
● 外側から内側の対話を意識する○ アクターとシステムの対話(外側から内側の対話)が示されていること。必要に応じて、GUIモックアップを書く。● ユースケース記述を、BCE(Boundary-Control-Entity)ステレオタイプで表現する。○ 名詞は、ドメインオブジェクトか、バウンダリオブジェクトになる。○ 動詞は、オブジェクト間のメッセージです。これは実装すべきソフトウェア機能(コントロール)を示している。システム境界とBCEステレオタイプアクター システムアクション応答システム境界エンティティ(ドメインオブジェクト )バウンダリコントロール(メッセージ)名詞(オブジェクト) 動詞(処理)ロバストネス分析の前提となる
● ユースケース○ イベントに参加する● 基本コース○ ユーザはイベントページへのリンクをクリックする。システムはイベントを取得し、それを表示する。それから、ユーザは参加ボタンをクリックする。システムは、そのイベントに参加者として登録する。● 代替コース○ 参加者枠がない場合:システムは、そのイベントに補欠者として登録する。ユースケース記述の例● ユースケース記述を短く書く。ユースケースの外部は書かない。イベントの表示に関することのみに集中する● ユースケースの範囲外の記述になりやすいため、事前条件と事後条件を排除する。<>関係でユースケースの順番を示す。● ドメインモデルに直接ユースケースを結びつけるため、ユビキタス言語を使って表現すること
● プロジェクトの用語(ユビキタス言語)で構成されたドメインオブジェクトを使って、ユースケースを記述する○ 曖昧な例■ ユーザはイベントページへのリンクをクリックする。システムはイベントを取得し、それを表示する。それから、ユーザは参加ボタンをクリックする。システムは、そのユーザが参加を希望するイベントに参加予定のユーザとして登録する。● ユースケース記述にバウンダリの用語を使う○ 「システムは、ウェブページを表示する」では曖昧すぎる。「システムは、イベント一覧ページを表示する」とするべき。「システムは、イベントカテゴリに基づくイベントリストを含むイベント一覧ページを表示する」とするとさらに明確になる。ユースケースにユビキタス言語を使う
● ユースケースからコードに落とし込むには、ユースケースをドメインオブジェクトに関連づける必要がある。そのために、ロバストネス分析を行う。ロバストネス図は、ユースケースをオブジェクトの絵として表現したもの。● ロバストネス分析では、ユースケース記述を分析し、最初のオブジェクト群(バウンダリ、ドメインオブジェクト、コントローラの三種類)を推定する。分析/概念設計/テクニカルアーキテクチャ何をどのように?ロバストネス分析の目的
● 名詞 ー 動詞 ー 名詞 の形式でユースケース記述をパターン化する○ 結合ルール■ 名詞は動詞とつなぐことができる(逆もまた同様)■ 名詞を他の名詞につなぐことができない■ 動詞は他の動詞とつなぐことができるロバストネス分析
● ユースケース記述の精査が終わると詳細設計に移る。● ユースケース記述で洗い出したした、アクターとBCEを中心としたシーケンス図を作成する● 通常とは異なる記法を利用します。○ シーケンス図上には、ユースケース記述に登場したコントロールが存在しない(責務があれば存在してもよい)。代わりに、コントロールはエンティティなどのオブジェクトへのメッセージに置き換えられます。○ このシーケンス図ではオブジェクトの動的な側面を分析するためであり、一般のシーケンス図のように手順の詳細を説明するものではありません。このため、活性区間も扱いません。設計/コーディング
シーケンス図を書き始める● ロバストネス図から、そのまま持ってくる● この段階では、まだエンティティには振る舞いがない(静的なドメインモデルであるため)● シーケンス図を描くことで、動的な側面を分析し、エンティティに振る舞いを割り当てる
エンティティに振る舞いを割り当てる● どのコントロールをエンティティに割り当てるべきかを考える○ そのエンティティとは何か?○ その操作は、どのクラスの責務(アクション、情報保持、判断)となるべきか?● オブジェクトデザインの格言○ ”責務は、ユースケース中のシステムの振る舞いに関する記述文やそこに暗示されているものから見つかる”○ “責務は、ユースケースや他のシステム記述に内在する抜けを埋めることでさらに見つかる”
やかんをただの物体とみるか否か● 物理的なオブジェクトは、仕事を行うか、情報を保持するだけで判断は行わない。電話帳オブジェクトは何も行わない。一方、サーモスタットは判断を行い、制御信号を送信する。やかんも容器の役割ぐらいしかない。しかし、分析によってどのような責務を与えるかで変わってくる● Alexanderが考えるやかんの責務○ 水をこぼしたり、しぶきをあげたりせずに中身を注ぐ○ 水を漏らすことがなく、沸騰するまで暖めることができる○ 水の沸騰を知らせる○ 安全な方法で運ぶための便利な手段を提供するこれらの洞察によって、平凡な貧血症オブジェクトになるか、ドメインリッチなオブジェクトになるかが決定づけられる
BCEだけは十分に分析できない場合● ロールステレオタイプ○ 情報保持役(Information Holder)は、情報を知り情報を提供する○ サービス提供役(Service Provider)は、仕事を行うが一般に演算サービスを提供する○ 構造役(Structrer)は、オブジェクト間の関係と、それらの関係についての情報を維持する○ インターフェイス役(Interfacer)は、システム内の異なる部分間で情報やリクエストを変換する○ 調整役(Coordinator)は、他のオブジェクトにタスクを委譲することでイベントに対応する○ 制御役(Controller)は、判断を行い他のオブジェクトのアクションを指示するエンティティ、値オブジェクト 情報保持役、構造役ビュー インターフェイス役コントローラ 調整役、制御役ドメインサービス サービス提供役アプリケーションサービス 調整役、制御役リポジトリ インターフェイス役ファクトリ 調整役
最終的なユースケース● フレームワークを意識してオブジェクトを見つける● コントロールをエンティティへのメッセージに変える● ドメインモデルやユースケースに不備があれば、フィードバックする
● RDRAでは、システム価値>システム外部環境>システム境界>システムの階層を使って、要件を捉えていくことに意味がある。○ コンテキストモデル、要求モデル、利用シーンはICONIXにはない考え方。境界づけられたコンテキストがどのようなものかを理解する助けになる。○ システム境界を跨がる際にプロトコルモデル/イベントモデルの観点は、アーキテクチャ設計を支援する。● ICONIXでは、ユビキタス言語で構成されたユースケース駆動によるオブジェクト指向設計を実現することに意味がある。○ ドメインモデリングとユースケースモデリングはドメインモデルの蒸留と実現するべきソフトウェア機能を具体的に洗い出す○ ロバストネス分析によって、静的なドメインモデルに動的な側面を付け加えていくことができる。RDRA, ICONIXの特徴
統合するためのヒントシステム価値システム外部環境システム境界システムユースケースモデル概念モデル ドメインモデル要求定義分析/概念設計/アーキテクチャ設計ドメインモデリングユースケースモデリング(ユースケース記述含む)ロバストネス分析不完全と仮定振り返るシーケンス図利用シーンコンテキストモデル要求モデル画面/帳票モデルプロトコル/イベントモデル必要最低限のものを選ぶデータモデル”何をどのように”のギャップを埋める機能モデル振り返る「探査 - 知覚 - 対応」のためのプロセスと捉えると両者を統合することができる。つまり、振り返りこそが重要。
● すべてを適用すると開発プロセスが重くなるのは自明。何も考えずに網羅的に実践するのは現実的ではない。ただ、観点だけは抑えておこう● 必要に応じて、プラクティスを選択することが重要● ただし、重要なものを外さないこと。以下を基本の軸にしてみてはどうだろうか○ コンテキストモデル (RDRA)○ 要求モデル (RDRA)○ ドメインモデリング (RDRA/ICONIX)○ ユースケースモデリング (RDRA/ICONIX)○ ロバストネス分析 (ICONIX)○ シーケンスモデル (ICONIX)● さらに簡単な部分ではなく、重要で複雑な部分から着手するとよいかもしれない。まとめ利害関係者と共に動的な側面をフィードバック
ご静聴ありがとうございました。