Claudeに問う「ドメイン駆動設計(DDD)のプラクティス(実践)を教えてください」

システム開発

昨日に続き、今度はドメイン駆動設計の具体的な実践方法を教えて貰います。
これを通じて日本企業のITへの取り組み方の問題点も見えてきます。

前の記事 → Claudeに問う「ドメイン駆動設計(DDD)について教えてください」

Claudeに問う

概要

DDD(ドメイン駆動設計)の具体的なプラクティス(実践)を詳しく教えてください。

ドメイン駆動設計(DDD)を実践する際には、以下のようなプラクティスが重要です:

  1. ドメインの理解と専門家との協業:

    • ドメインエキスパートと協力し、問題領域を深く理解します。
    • ドメインエキスパートとの継続的な対話を通じて、ドメインモデルを洗練させていきます。
    • ユビキタス言語を使用して、開発チームとドメインエキスパートの間で効果的にコミュニケーションを行います。
  2. ドメインモデルの作成:

    • ドメインの中核となる概念、エンティティ、値オブジェクトを特定します。
    • オブジェクト間の関係性とビジネスルールを明確にします。
    • ドメインモデルを表現するために、図やダイアグラムを活用します(例:UMLクラス図、シーケンス図など)。
  3. アーキテクチャの設計:

    • レイヤードアーキテクチャを採用し、ドメイン層、アプリケーション層、インフラストラクチャ層を分離します。
    • ドメインモデルを中心に据え、他の層はドメインモデルに依存するようにします。
    • インターフェースを使用して、層間の依存関係を制御します。
  4. 境界づけられたコンテキストの特定:

    • 複雑なドメインを、より管理しやすい境界づけられたコンテキストに分割します。
    • 各コンテキストには、独自のドメインモデルとユビキタス言語が存在します。
    • コンテキスト間の関係性とコミュニケーション方法を明確にします。
  5. リポジトリパターンの実装:

    • リポジトリを使用して、ドメインオブジェクトの永続化と検索を行います。
    • リポジトリは、ドメインモデルとインフラストラクチャ層を分離するための抽象化レイヤーとして機能します。
    • リポジトリのインターフェースは、ドメインの言葉で表現されます。
  6. ドメインイベントの活用:

    • ドメインで発生した重要な出来事をドメインイベントとして表現します。
    • イベントを使用して、オブジェクト間の疎結合な相互作用を実現します。
    • イベントハンドラを実装して、イベントに応じた適切なアクションを実行します。
  7. 継続的なリファクタリング:

    • ドメインモデルを常に進化させ、新しい知見を取り入れます。
    • コードのリファクタリングを定期的に行い、設計の品質を維持します。
    • テストを充実させ、リファクタリングによる影響を最小限に抑えます。
  8. チームの組織化:

    • 機能横断的なチームを編成し、各チームがドメインの一部に責任を持つようにします。
    • チーム内で密にコミュニケーションを行い、知識の共有を促進します。
    • チーム間の調整には、境界づけられたコンテキストを活用します。

これらのプラクティスを適用することで、ドメインモデルを中心とした柔軟で保守性の高いソフトウェアを開発することができます。ただし、DDDは画一的なプロセスではなく、プロジェクトやチームの状況に応じて適応していく必要があります。継続的な学習と改善が、DDDの実践には欠かせません。

「DDDの主な目的は、ソフトウェアの設計と実装をビジネスドメインに密接に関連付けること」との事でしたが、このプラクティスでビジネスドメインとソフトウェア実装は、互いにどこで繋がるのでしょうか。

ドメイン駆動設計(DDD)では、ビジネスドメインとソフトウェア実装の間に密接な関係を築くことを目的としています。この関係は、主に以下の要素を通じて実現されます:

  1. ユビキタス言語:

    • ドメインエキスパートと開発チームが共通の言語を使用することで、ビジネスの概念とソフトウェアの実装の間にギャップが生まれにくくなります。
    • ユビキタス言語は、コードやドキュメント、ディスカッションなどあらゆる場面で使用されます。
  2. ドメインモデル:

    • ドメインモデルは、ビジネスドメインの中核となる概念、エンティティ、値オブジェクトを表現します。
    • ドメインモデルは、ビジネスルールや制約を反映し、ドメインの言葉で表現されます。
    • このドメインモデルが、ソフトウェアの設計と実装の基礎となります。
  3. アーキテクチャ:

    • レイヤードアーキテクチャを採用し、ドメイン層を中心に据えることで、ビジネスロジックとソフトウェアの実装が密接に関連付けられます。
    • ドメイン層には、ドメインモデルとビジネスロジックが配置され、他の層はドメイン層に依存します。
  4. コードの表現:

    • ドメインモデルの概念は、コードにも直接反映されます。クラス名、メソッド名、変数名などに、ユビキタス言語の用語が使用されます。
    • これにより、コードとビジネスドメインの間の関係が明確になり、コードの理解性が向上します。
  5. 継続的なコラボレーション:

    • 開発チームとドメインエキスパートが継続的に協力し、ドメインモデルを洗練させていきます。
    • 新しい要件や変更は、ドメインモデルに反映され、それに基づいてソフトウェアが進化します。

これらの要素を通じて、ビジネスドメインとソフトウェア実装の間に強い結びつきが生まれます。ドメインの言葉がソフトウェアに直接反映され、ソフトウェアの構造がドメインの概念に沿ったものになります。

また、DDDでは、ソフトウェアの実装からドメインの理解を深めるという逆方向の流れも重要視されます。実装を通じて得られた洞察をドメインモデルにフィードバックし、モデルを洗練させていくことが求められます。

このような双方向のやり取りを通じて、ビジネスドメインとソフトウェア実装の間に密接な関係が築かれ、ソフトウェアがビジネスの要求に柔軟に適応できるようになるのです。

1. ドメインの理解と専門家との協業

プラクティスの解説項目を、一つずつ順番に解説してください。

まず、「1. ドメインの理解と専門家との協業」について、詳しく解説してください。

「ドメインの理解と専門家との協業」は、ドメイン駆動設計(DDD)において非常に重要な実践です。この実践は、開発チームがビジネスドメインを深く理解し、ドメインエキスパートと密接に協力することを目的としています。

具体的には、以下のような活動が含まれます:

  1. ドメインエキスパートとの対話:

    • 開発チームは、ドメインエキスパートと定期的に会議を行い、ビジネスの要件や課題について議論します。
    • ドメインエキスパートは、業務の流れ、ビジネスルール、例外的なケースなどを説明し、開発チームの理解を深めます。
    • 対話を通じて、開発チームはドメインの専門用語や概念を学び、ユビキタス言語の基礎を築きます。
  2. ドメインの知識の獲得:

    • 開発チームは、ドメインに関する資料(業務マニュアル、規定書、既存システムのドキュメントなど)を読み込み、ドメインの知識を獲得します。
    • ドメインエキスパートに質問し、曖昧な点や矛盾点を明らかにしていきます。
    • 必要に応じて、ワークショップやブレインストーミングセッションを開催し、ドメインの理解を深めます。
  3. ドメインモデリング:

    • 獲得したドメインの知識を基に、開発チームはドメインモデルの作成に着手します。
    • エンティティ、値オブジェクト、集約、ドメインサービスなどの概念を用いて、ドメインを表現するオブジェクトモデルを構築します。
    • ドメインエキスパートと協力し、モデルが業務の実態を正確に反映していることを確認します。
  4. ユビキタス言語の確立:

    • ドメインモデリングを通じて、開発チームとドメインエキスパートの間で共通の言語(ユビキタス言語)を確立します。
    • ユビキタス言語は、コードやドキュメント、ディスカッションなどあらゆる場面で使用されます。
    • ユビキタス言語を使うことで、開発チームとドメインエキスパートの間のコミュニケーションが円滑になり、誤解が減ります。
  5. 継続的な協業:

    • ドメインの理解と専門家との協業は、一度で完了するものではありません。
    • プロジェクトを通じて、開発チームとドメインエキスパートは継続的に協力し、ドメインモデルを洗練させていきます。
    • 新しい要件や変更が生じた場合は、ドメインエキスパートと議論し、モデルに反映します。

ドメインの理解と専門家との協業は、DDDの中核をなす実践です。この実践を通じて、開発チームはビジネスドメインに対する深い理解を得ることができ、ソフトウェアがビジネスの要求に適合することが保証されます。また、ドメインエキスパートと開発チームの間の信頼関係が築かれ、プロジェクトの成功確率が高まります。

2. ドメインモデルの作成

次に「2. ドメインモデルの作成」について、詳しく解説してください。

「ドメインモデルの作成」は、ドメイン駆動設計(DDD)において、ビジネスドメインを正確に表現するためのキーとなる実践です。ドメインモデルは、ドメインの中核となる概念、エンティティ、値オブジェクトを表現し、オブジェクト間の関係性とビジネスルールを明確にします。

ドメインモデルを作成する際には、以下のようなステップが含まれます:

  1. ドメインの中核となる概念の特定:

    • ドメインエキスパートとの対話や、ドメインの知識の獲得を通じて、ドメインの中核となる概念を特定します。
    • 中核となる概念は、ビジネスの価値を生み出す上で重要な役割を果たすものです。
    • これらの概念は、エンティティ、値オブジェクト、集約などの形でドメインモデルに反映されます。
  2. エンティティと値オブジェクトの識別:

    • ドメインの概念を、エンティティと値オブジェクトに分類します。
    • エンティティは、一意の識別子を持ち、ライフサイクルを通じて変化するオブジェクトです。
    • 値オブジェクトは、不変で、同じ属性を持つインスタンスは交換可能であるオブジェクトです。
  3. オブジェクト間の関係性の定義:

    • エンティティと値オブジェクトの間の関係性を明確にします。
    • 関連(Association)、集約(Aggregation)、コンポジション(Composition)などの関係を使って、オブジェクト間の構造を表現します。
    • 関係性には、多重度(Multiplicity)やナビゲーション可能性も指定します。
  4. ビジネスルールの組み込み:

    • ドメインのビジネスルールや制約をドメインモデルに組み込みます。
    • ビジネスルールは、エンティティのメソッドやドメインサービスとして実装されます。
    • ビジネスルールを明示的にモデル化することで、ドメインの不変条件を保証し、モデルの整合性を維持します。
  5. 集約の設計:

    • 関連するエンティティと値オブジェクトをまとめて、集約(Aggregate)を形成します。
    • 集約は、一貫性の境界を定義し、ビジネスルールを適用する単位となります。
    • 集約は、ルートエンティティを持ち、外部からはルートエンティティを介してアクセスされます。
  6. リポジトリインターフェースの定義:

    • 集約の永続化と読み込みを行うためのリポジトリのインターフェースを定義します。
    • リポジトリのメソッドは、ドメインの言葉で表現され、クエリの詳細は隠蔽されます。
  7. ドメインモデルの検証と洗練:

    • ドメインエキスパートと協力して、作成したドメインモデルが業務の実態を正確に反映していることを検証します。
    • フィードバックを受けて、モデルを洗練し、より正確で表現力の高いものにしていきます。

ドメインモデルの作成は、反復的かつ段階的に行われます。モデルは、プロジェクトの進行に伴って進化し、新しい知見や変更を取り入れていきます。

ドメインモデルは、ソフトウェアの設計と実装の基礎となるだけでなく、開発チームとドメインエキスパートの間のコミュニケーションツールとしても機能します。モデルを通じて、双方の理解が深まり、より適切なソフトウェアが開発できるようになります。

3. アーキテクチャの設計

次に「3. アーキテクチャの設計」について、詳しく解説してください。

「アーキテクチャの設計」は、ドメイン駆動設計(DDD)において、ソフトウェアシステムの全体的な構造を定義し、ドメインモデルを中心に据えた設計を行うための重要な実践です。DDDでは、通常、レイヤードアーキテクチャが採用され、ドメイン層、アプリケーション層、インフラストラクチャ層に分割されます。

アーキテクチャを設計する際には、以下のような点に留意します:

  1. ドメイン層の分離:

    • ドメイン層には、ドメインモデル(エンティティ、値オブジェクト、集約、リポジトリインターフェースなど)とドメインサービスを配置します。
    • ドメイン層は、ビジネスロジックを含み、ドメインの概念や用語で表現されます。
    • ドメイン層は、他の層に依存してはならず、ビジネスルールの変更が他の層に影響を与えないようにします。
  2. アプリケーション層の役割:

    • アプリケーション層は、ユースケースを実装し、ドメイン層とインフラストラクチャ層の間を調整します。
    • アプリケーション層は、ドメインオブジェクトを操作し、トランザクション管理や例外処理を行います。
    • アプリケーション層は、ユーザーインターフェースや外部システムとのインタラクションを制御します。
  3. インフラストラクチャ層の分離:

    • インフラストラクチャ層には、データベースアクセス、外部サービスとの通信、ログ出力などの技術的な詳細を実装します。
    • インフラストラクチャ層は、ドメイン層やアプリケーション層の要求に応じてサービスを提供します。
    • インフラストラクチャ層の実装は、他の層から隔離され、技術の変更がドメインロジックに影響を与えないようにします。
  4. 依存関係の方向:

    • 依存関係は、常に上位の層から下位の層に向かうようにします。
    • ドメイン層は、アプリケーション層やインフラストラクチャ層に依存してはいけません。
    • アプリケーション層は、ドメイン層に依存しますが、インフラストラクチャ層に依存してはいけません。
  5. インターフェースの使用:

    • 層間の依存関係を制御するために、インターフェースを使用します。
    • 上位の層は、下位の層のインターフェースのみに依存し、実装の詳細は知る必要がありません。
    • インターフェースを使うことで、各層の実装を独立して変更できるようになります。
  6. ドメインイベントの伝播:

    • ドメインイベントを使って、ドメイン層内の変更を他の層に伝播させます。
    • アプリケーション層は、ドメインイベントを受信し、適切なアクションを実行します。
    • ドメインイベントは、層間の疎結合なコミュニケーションを実現します。
  7. 境界づけられたコンテキストの考慮:

    • 複雑なドメインを、境界づけられたコンテキストに分割し、各コンテキストごとにアーキテクチャを設計します。
    • コンテキスト間の関係性と依存関係を明確にし、コンテキスト間の統合方法を定義します。

DDDにおけるアーキテクチャ設計は、ドメインモデルを中心に据え、ビジネスロジックとインフラストラクチャの詳細を分離することを目的としています。これにより、ドメインの複雑性を管理し、変更に強い柔軟なシステムを構築することができます。

また、アーキテクチャ設計は、チームの構成にも影響を与えます。各層やコンテキストごとにチームを編成し、独立して開発や保守ができるようにすることが望ましいとされています。

アーキテクチャ設計は、プロジェクトの初期段階だけでなく、開発を進める中で継続的に見直しと改善が行われます。フィードバックを受けて、より適切な設計へと進化させていくことが重要です。

4. 境界づけられたコンテキストの特定

次に「4. 境界づけられたコンテキストの特定」について、詳しく解説してください。

「境界づけられたコンテキストの特定」は、ドメイン駆動設計(DDD)において、複雑なドメインを管理可能な部分に分割するための重要な実践です。境界づけられたコンテキスト(Bounded Context)は、一貫した概念モデルを持ち、明確な境界線によって他のコンテキストから分離された、ドメインの一部分を表します。

境界づけられたコンテキストを特定する際には、以下のような手順が含まれます:

  1. ドメインの分析:

    • ドメインエキスパートとの対話や、ドメインの知識の獲得を通じて、ドメインを詳細に分析します。
    • ドメインの概念、用語、プロセス、ルールなどを明確にし、ドメインの全体像を把握します。
  2. サブドメインの識別:

    • ドメインを、関連する概念や機能ごとにサブドメインに分割します。
    • サブドメインは、ドメイン内の論理的な境界を表し、独自の言語やルールを持ちます。
    • サブドメインは、ビジネスの観点から意味のあるまとまりである必要があります。
  3. コンテキストマッピング:

    • サブドメイン間の関係性を分析し、コンテキストマップを作成します。
    • コンテキストマップでは、各サブドメインを境界づけられたコンテキストとして表現し、コンテキスト間の関係性を明示します。
    • 関係性には、共有カーネル、顧客-供給者、準拠者、セパレートウェイズなどのパターンがあります。
  4. 境界線の明確化:

    • 各境界づけられたコンテキストの境界線を明確にします。
    • 境界線は、コンテキスト間でモデルや概念が異なる部分、コンテキスト間の依存関係が変更される部分などに引かれます。
    • 境界線を明確にすることで、コンテキスト間の結合度を下げ、変更の影響範囲を限定することができます。
  5. コンテキスト内のモデリング:

    • 各境界づけられたコンテキスト内で、独自のドメインモデルを作成します。
    • コンテキスト内のモデルは、そのコンテキストに固有の言語や概念を反映し、他のコンテキストとは独立して進化します。
    • コンテキスト内のモデリングでは、エンティティ、値オブジェクト、集約などの設計要素を使用します。
  6. コンテキスト間のインテグレーション:

    • 境界づけられたコンテキスト間で情報をやり取りする必要がある場合、コンテキスト間のインテグレーション方法を定義します。
    • インテグレーションには、RESTful API、メッセージング、イベントドリブンアーキテクチャなどの手法が使用されます。
    • インテグレーションは、コンテキスト間の結合度を最小限に抑えるように設計します。
  7. 継続的なリファインメント:

    • 境界づけられたコンテキストは、プロジェクトの進行に伴って洗練されていきます。
    • 新しい要件や変更に応じて、コンテキストの境界線を見直し、モデルを更新します。
    • フィードバックを受けて、より適切なコンテキスト分割とモデリングを目指します。

境界づけられたコンテキストの特定は、複雑なドメインを扱う上で非常に重要な実践です。適切にコンテキストを分割することで、モデルの複雑性を管理し、変更の影響を局所化することができます。また、コンテキストごとに独立したチームを編成し、並行して開発を進めることが可能になります。

境界づけられたコンテキストの特定は、ドメインの理解と専門家との協業、ドメインモデリングと密接に関連しています。これらの実践を組み合わせることで、効果的なドメイン駆動設計を実現することができます。

5. リポジトリパターンの実装

次に「5. リポジトリパターンの実装」について、詳しく解説してください。

「リポジトリパターンの実装」は、ドメイン駆動設計(DDD)において、ドメインオブジェクトの永続化と検索を抽象化するためのパターンです。リポジトリは、ドメイン層とインフラストラクチャ層の間に位置し、ドメインオブジェクトをデータストアに保存したり、データストアから読み込んだりするための操作を提供します。

リポジトリパターンを実装する際には、以下のような手順が含まれます:

  1. リポジトリインターフェースの定義:

    • ドメイン層に、リポジトリのインターフェースを定義します。
    • インターフェースには、ドメインオブジェクトの永続化と検索に必要なメソッドを宣言します。
    • メソッドのシグネチャは、ドメインの言葉で表現し、実装の詳細を隠蔽します。
  2. リポジトリの実装:

    • インフラストラクチャ層に、リポジトリインターフェースの実装クラスを作成します。
    • 実装クラスは、データストア(リレーショナルデータベース、NoSQLデータベース、ファイルシステムなど)との対話を担当します。
    • データストアとの対話には、O/Rマッパー(Object-Relational Mapper)やODM(Object-Document Mapper)などのツールを使用することが一般的です。
  3. ドメインオブジェクトの永続化:

    • リポジトリの実装クラスに、ドメインオブジェクトを保存するためのメソッドを実装します。
    • メソッドは、ドメインオブジェクトをデータストアに適した形式に変換し、データストアに保存します。
    • 保存する際は、トランザクション管理にも配慮します。
  4. ドメインオブジェクトの検索:

    • リポジトリの実装クラスに、ドメインオブジェクトを検索するためのメソッドを実装します。
    • メソッドは、データストアに対してクエリを実行し、結果をドメインオブジェクトに変換して返します。
    • 検索条件は、ドメインの言葉で表現され、データストアの詳細は隠蔽されます。
  5. 集約の境界の尊重:

    • リポジトリは、集約(Aggregate)の境界を尊重します。
    • 集約は、一貫性の境界を表し、リポジトリは集約のルートエンティティを通じてアクセスされます。
    • リポジトリは、集約内のエンティティや値オブジェクトを直接操作せず、常に集約のルートエンティティを経由します。
  6. リポジトリの使用:

    • アプリケーション層やドメインサービスは、リポジトリのインターフェースを通じてドメインオブジェクトの永続化と検索を行います。
    • リポジトリの実装の詳細は、呼び出し側から隠蔽されます。
    • リポジトリを使用することで、ドメイン層とインフラストラクチャ層の結合度を下げ、変更の影響範囲を限定することができます。
  7. テストの容易性:

    • リポジトリのインターフェースを定義することで、ドメイン層のテストが容易になります。
    • テスト時は、リポジトリの実装をモックやスタブに置き換えることができます。
    • これにより、データストアに依存せずにドメインロジックのテストを行うことができます。

リポジトリパターンは、ドメインモデルとインフラストラクチャの詳細を分離するための重要な仕組みです。リポジトリを使用することで、ドメインオブジェクトの永続化と検索に関する関心事をドメイン層から切り離し、インフラストラクチャ層に委譲することができます。

また、リポジトリは、データストアの実装を隠蔽するため、データストアの変更がドメイン層に影響を与えることを防ぎます。これにより、ドメインモデルの保守性と柔軟性が向上します。

リポジトリパターンは、DDDにおける重要な実践の一つであり、ドメインモデルの純粋性を維持しつつ、永続化の詳細を抽象化するための有効な手段です。

6. ドメインイベントの活用

次に「6. ドメインイベントの活用」について、詳しく解説してください。

「ドメインイベントの活用」は、ドメイン駆動設計(DDD)において、ドメインモデル内の重要な出来事を表現し、モジュール間の疎結合なコミュニケーションを実現するための重要な概念です。ドメインイベントは、ドメインで発生した出来事を表すオブジェクトであり、イベントが発生した際に他のモジュールに通知することで、モジュール間の連携を促進します。

ドメインイベントを活用する際には、以下のような手順が含まれます:

  1. イベントの識別:

    • ドメインモデルを分析し、重要な出来事や状態の変化を識別します。
    • これらの出来事が、他のモジュールに通知すべきイベントとなります。
    • イベントは、ドメインの言葉で表現され、ドメインの専門家にとって意味のあるものでなければなりません。
  2. イベントの定義:

    • 識別したイベントを表現するためのクラスを定義します。
    • イベントクラスには、イベントに関連する情報(発生時刻、関連するエンティティの識別子など)を保持するためのプロパティを定義します。
    • イベントクラスは、不変(Immutable)であることが望ましいです。
  3. イベントの発行:

    • ドメインモデル内で、イベントが発生する箇所を特定します。
    • イベントが発生した際に、イベントオブジェクトを生成し、イベントパブリッシャー(イベントの発行を担当するオブジェクト)に渡します。
    • イベントパブリッシャーは、イベントを登録済みのイベントハンドラー(イベントの処理を担当するオブジェクト)に通知します。
  4. イベントの処理:

    • イベントハンドラーは、受け取ったイベントを処理します。
    • イベントハンドラーは、イベントに応じて、他のエンティティの状態を更新したり、別のイベントを発行したりします。
    • イベントハンドラーは、イベントを受け取った際に、トランザクション境界を考慮して処理を行います。
  5. イベントの伝播:

    • ドメインイベントは、発生したコンテキスト内だけでなく、他のコンテキストにも伝播させることができます。
    • コンテキスト間でイベントを伝播させることで、システム全体の整合性を保つことができます。
    • イベントの伝播には、メッセージングシステムやイベントバスなどのインフラストラクチャを活用します。
  6. イベントソーシング:

    • ドメインイベントを永続化し、システムの状態をイベントの連鎖として表現する手法を、イベントソーシングと呼びます。
    • イベントソーシングでは、エンティティの状態を直接保存するのではなく、エンティティに対して行われた操作を表すイベントを保存します。
    • 保存されたイベントを再生することで、エンティティの状態を復元することができます。
  7. CQRS(Command Query Responsibility Segregation)との組み合わせ:

    • ドメインイベントは、CQRS パターンと組み合わせて使用されることがあります。
    • CQRS では、システムを更新を担当するコマンド側と、読み取りを担当するクエリ側に分離します。
    • ドメインイベントは、コマンド側で発行され、クエリ側で購読されることで、コマンドとクエリの同期を実現します。

ドメインイベントの活用は、DDDにおける重要な実践の一つです。ドメインイベントを用いることで、モジュール間の疎結合性を高め、システムの拡張性と保守性を向上させることができます。また、イベントソーシングやCQRSなどの高度な手法と組み合わせることで、より柔軟で応答性の高いシステムを構築することができます。

ただし、ドメインイベントの導入には、イベントの識別、イベントの伝播方法、イベントの処理順序などに関する設計上の課題があります。これらの課題に適切に対処するために、チームでの合意形成とアーキテクチャ上の工夫が必要です。

ドメインイベントは、DDDにおけるドメインモデルの表現力を高め、モジュール間の連携を促進するための強力な手段です。適切に活用することで、ドメインの変化に柔軟に対応できる、より進化可能なシステムを構築することができます。

7. 継続的なリファクタリング

次に「7. 継続的なリファクタリング」について、詳しく解説してください。

「継続的なリファクタリング」は、ドメイン駆動設計(DDD)において、ドメインモデルを常に進化させ、設計の品質を維持するための重要な実践です。リファクタリングとは、外部から見たシステムの動作を変えることなく、内部の構造を改善するプロセスのことを指します。DDDでは、ドメインの理解が深まるにつれて、ドメインモデルを継続的に洗練していく必要があります。

継続的なリファクタリングを実践する際には、以下のような手順が含まれます:

  1. ドメインの理解の深化:

    • ドメインエキスパートとの対話や、システムの利用を通じて、ドメインに関する新しい洞察や知見を得ます。
    • ドメインの理解が深まるにつれて、ドメインモデルの改善点や、新しい概念の導入の必要性が明らかになります。
  2. リファクタリングの計画:

    • ドメインモデルの改善点を特定し、リファクタリングの計画を立てます。
    • リファクタリングの目的を明確にし、期待される効果を評価します。
    • リファクタリングの範囲と優先順位を決定し、適切なタイミングを選択します。
  3. テストの整備:

    • リファクタリングを安全に行うために、十分なテストを用意します。
    • ユニットテスト、統合テスト、受け入れテストなどを整備し、リファクタリング前後でシステムの動作が変わらないことを確認します。
    • テストは、リファクタリングの安全ネットとして機能し、変更による影響を早期に検出することができます。
  4. コードの改善:

    • リファクタリングの計画に基づいて、コードを段階的に改善します。
    • 設計原則(SOLID原則など)やデザインパターンを適用し、コードの可読性、保守性、拡張性を高めます。
    • ドメインの言葉に合わせてコードを調整し、よりドメインモデルに近い表現を目指します。
  5. ドメインモデルの進化:

    • リファクタリングを通じて、ドメインモデルを洗練させます。
    • 新しい概念や関係性を導入し、ドメインモデルの表現力を高めます。
    • ドメインモデルの進化に合わせて、ユビキタス言語も更新します。
  6. フィードバックの収集:

    • リファクタリング後のドメインモデルについて、ドメインエキスパートからフィードバックを収集します。
    • フィードバックを基に、さらなる改善点を特定し、次のリファクタリングサイクルにつなげます。
  7. 継続的な改善:

    • リファクタリングは一時的なものではなく、継続的に行われるプロセスです。
    • ドメインの理解が深まるにつれて、繰り返しリファクタリングを行い、ドメインモデルを常に進化させ続けます。
    • 継続的なリファクタリングにより、設計の腐敗を防ぎ、ドメインモデルの品質を維持することができます。

継続的なリファクタリングは、DDDにおける重要な実践の一つです。ドメインの理解が深まるにつれてドメインモデルを進化させることで、より正確で表現力の高いモデルを構築することができます。また、リファクタリングを通じてコードの品質を維持することで、システムの保守性と拡張性を向上させることができます。

ただし、リファクタリングには一定のコストがかかるため、適切なタイミングとバランスが必要です。リファクタリングの効果と、それに必要な工数を見極め、チーム全体で合意を形成しながら進めることが重要です。

継続的なリファクタリングは、DDDにおけるドメインモデルの進化と、設計の品質維持に欠かせない実践です。これを適切に行うことで、常に変化し続けるビジネス要求に対応できる、柔軟で長期的に維持可能なシステムを構築することができます。

念のための確認ですが、このリファクタリングはユビキタス言語で表記されたドメインモデルやリポジトリの設計のリファクタリングを意味し、ソフトウェアのソースコードのリファクタリングではありませんよね。

ご指摘ありがとうございます。私の説明が不十分でした。ドメイン駆動設計(DDD)における継続的なリファクタリングは、ユビキタス言語で表現されたドメインモデルの改善だけでなく、ソフトウェアのソースコードのリファクタリングも含みます。

DDDでは、ドメインモデルとソフトウェアの実装が密接に関連しているため、ドメインモデルの進化に合わせてソースコードも継続的に改善していく必要があります。つまり、リファクタリングの対象は以下の両方を含みます:

  1. ドメインモデルのリファクタリング:

    • ユビキタス言語の洗練
    • エンティティ、値オブジェクト、集約などの設計の見直し
    • ドメインサービスの責務の調整
    • リポジトリインターフェースの改善
  2. ソースコードのリファクタリング:

    • ドメインモデルの変更に合わせたコードの修正
    • 設計原則(SOLID原則など)の適用
    • デザインパターンの導入
    • コードの可読性、保守性、拡張性の向上

ドメインモデルとソースコードは相互に影響し合うため、両者を整合性のある状態に保つためには、継続的なリファクタリングが必要です。ドメインモデルの改善だけでなく、それに対応するソースコードの改善も行うことで、ソフトウェアの品質を維持し、ドメインの変化に対応しやすくなります。

したがって、DDDにおける継続的なリファクタリングは、ドメインモデルとソースコードの両方を対象とし、それらを常に進化させ、設計の品質を維持するための包括的な実践だと言えます。

私の前の説明が不明瞭で混乱を招いてしまい申し訳ありません。ご指摘いただきありがとうございました。

8. チームの組織化

その件については、また後で質問します。

先にプラクティスの最後に「8. チームの組織化」について、詳しく解説してください。

「チームの組織化」は、ドメイン駆動設計(DDD)を効果的に実践するための重要な要素です。DDDでは、ドメインの専門知識を持つチームメンバーが協調して働くことが求められます。チームの組織化は、この協調を促進し、ドメインの理解を深め、ソフトウェアの品質を向上させるために欠かせません。

チームの組織化において考慮すべき点は以下の通りです:

  1. 機能横断的なチーム編成:

    • チームは、特定の機能やコンポーネントではなく、ドメインの境界に沿って編成します。
    • 各チームは、担当するドメインの一部または全体に責任を持ちます。
    • チームには、開発者、ドメインエキスパート、QAエンジニア、UIデザイナーなど、様々な専門性を持つメンバーが含まれます。
  2. 自己組織化と自律性:

    • チームは、自己組織化され、自律的に働くことが求められます。
    • チームメンバーは、協力してタスクを計画し、実行し、改善していきます。
    • 上位の管理者は、チームの自律性を尊重し、適切なサポートと方向性を提供します。
  3. コミュニケーションの促進:

    • チーム内のコミュニケーションを促進するために、頻繁なミーティングやディスカッションを行います。
    • ドメインエキスパートと開発者が密接に協力し、ドメインの知識を共有し、ユビキタス言語を洗練させていきます。
    • チーム間のコミュニケーションも重要で、必要に応じて他のチームとの調整や情報共有を行います。
  4. 技術的な自律性:

    • 各チームは、担当するドメインに適した技術スタックやツールを選択する自由を持ちます。
    • チームは、自らの技術的な意思決定に責任を持ち、システムの品質と保守性を維持します。
    • ただし、全体のアーキテクチャやインフラストラクチャとの整合性は維持する必要があります。
  5. 継続的な学習と改善:

    • チームは、継続的な学習と改善の文化を育みます。
    • 新しい技術やプラクティスを積極的に取り入れ、スキルを向上させていきます。
    • レトロスペクティブを定期的に行い、プロセスの改善点を特定し、実行に移します。
  6. ドメインエキスパートとの連携:

    • チームは、ドメインエキスパートとの緊密な連携を維持します。
    • ドメインエキスパートは、チームの一員として扱われ、開発プロセスに積極的に関与します。
    • ドメインエキスパートの知識を最大限に活用し、ドメインモデルの品質を高めていきます。
  7. コンテキスト間の調整:

    • 複数のチームが異なる境界づけられたコンテキストを担当する場合、チーム間の調整が必要になります。
    • コンテキストマップを活用し、コンテキスト間の関係性と依存関係を明確にします。
    • チーム間で定期的な調整ミーティングを行い、インテグレーションポイントや共通の課題について議論します。

チームの組織化は、DDDの実践において重要な役割を果たします。機能横断的なチーム編成、自律性の尊重、コミュニケーションの促進、継続的な学習と改善、ドメインエキスパートとの連携など、様々な側面に配慮することで、チームはドメインの理解を深め、高品質のソフトウェアを効率的に開発することができます。

DDDは、単なる技術的な手法ではなく、チームとしての協調と成長を促すアプローチでもあります。チームの組織化に注力することで、DDDの真価を発揮し、ビジネス要求に柔軟に対応できる強力なチームを育成することができるのです。

DDDとプロセスモデルの組み合わせ

プラクティスの説明を全て聞いても、DDD(ドメイン駆動設計)の成果物であるユビキタス言語で表記された設計図と、具体的なコーディングとデバッグを伴うソフトウェア開発とが、どこで結びつくのか良く分かりません。
また、DDD(ドメイン駆動設計)で設計した場合、ソフトウェア開発プロセスモデルはどのモデルを採用するべきなのかも見えてきません。
その辺の説明をお願いします。

ご質問ありがとうございます。ドメイン駆動設計(DDD)における設計とソフトウェア開発の関係性、およびDDDに適したソフトウェア開発プロセスモデルについて説明します。

  1. ユビキタス言語で表記された設計とソフトウェア開発の結びつき: DDDでは、ユビキタス言語を用いてドメインモデルを表現します。このドメインモデルは、ソフトウェア開発における設計の基礎となります。具体的には、以下のようにドメインモデルとソフトウェア開発が結びつきます:

    • ドメインモデルのエンティティ、値オブジェクト、集約などの概念は、ソフトウェアのクラス、インターフェース、モジュールなどに直接マッピングされます。
    • ドメインモデルで表現されたビジネスルールや制約は、ソフトウェアの振る舞いとして実装されます。
    • リポジトリやドメインサービスなどのドメインモデルの要素は、ソフトウェアのコンポーネントやサービスとして実現されます。

    つまり、ユビキタス言語で表現されたドメインモデルは、ソフトウェア開発者にとって設計の青写真となります。開発者は、このドメインモデルを基にコードを書き、ドメインの概念を忠実に表現するソフトウェアを実装します。

  2. ソフトウェア開発プロセスモデルとDDD: DDDは、特定のソフトウェア開発プロセスモデルを規定していませんが、反復的かつ漸進的なアプローチと相性が良いとされています。代表的なプロセスモデルとその適用方法は以下の通りです:

    • アジャイル開発(スクラム、XPなど): DDDは、アジャイル開発の原則と価値観に合致しています。短いイテレーションで開発を進め、ドメインエキスパートとの頻繁なフィードバックを得ながらドメインモデルを洗練させていきます。ユーザーストーリーやバックログアイテムは、ドメインの言葉で表現され、ドメインモデルと紐づけられます。
    • 反復的な開発プロセス(RUP、スパイラルモデルなど): 反復的な開発プロセスでは、各イテレーションでドメインモデルを段階的に拡張し、詳細化していきます。設計と実装を繰り返し行いながら、ドメインの理解を深めていきます。DDDのプラクティスは、各イテレーションで適用され、ドメインモデルの品質を高めていきます。
    • ウォーターフォールモデル: ウォーターフォールモデルは、DDDとの相性があまり良くありません。ただし、初期段階で集中的にドメインモデリングを行い、設計を固めてから実装に移ることは可能です。ただし、ドメインの理解が深まるにつれて設計を変更する柔軟性が求められます。

    DDDは、ドメインモデルの構築と洗練に重点を置くため、ドメインエキスパートとの協業と頻繁なフィードバックが得られるプロセスモデルが適しています。アジャイル開発や反復的な開発プロセスは、DDDの実践と相性が良く、ドメインモデルの進化とソフトウェアの開発を効果的に組み合わせることができます。

重要なのは、選択したプロセスモデルにかかわらず、DDDの原則とプラクティスを適用し、ドメインモデルを中心に据えた開発を行うことです。ドメインモデルとソフトウェア開発を密接に結びつけ、ドメインの専門家と開発チームが協調して働ける環境を整えることが、DDDの成功につながります。

念のために、もう一つ確認しておきたいのですが、アグリゲートはどの段階で設計するのでしょうか。
プラクティスの解説には登場しなかったと思います。

アグリゲートの設計は、ドメインモデリングの段階で行われます。具体的には、「2. ドメインモデルの作成」の一部として位置づけられます。アグリゲートは、ドメインモデルの中核をなす要素の一つであり、複数のエンティティや値オブジェクトを一つのまとまりとして扱うことで、ドメインの不変条件を維持し、ビジネスルールを適用するための重要な設計概念です。

アグリゲートの設計は、以下のような手順で行われます:

  1. エンティティと値オブジェクトの識別: ドメインの概念を分析し、エンティティと値オブジェクトを特定します。エンティティは一意の識別子を持ち、ライフサイクルを通じて変化する概念を表します。値オブジェクトは、不変で交換可能な概念を表します。
  2. 関連する概念のグルーピング: 識別したエンティティと値オブジェクトの中で、密接に関連し、一貫性を保つ必要がある概念をグループ化します。これらのグループが、アグリゲートの候補となります。
  3. 不変条件の特定: 各アグリゲートについて、維持すべき不変条件を特定します。不変条件は、アグリゲート内のエンティティや値オブジェクトが満たすべきビジネスルールや制約を表します。
  4. ルートエンティティの選択: 各アグリゲートについて、ルートエンティティを選択します。ルートエンティティは、アグリゲートの識別子を持ち、アグリゲートへのアクセスポイントとなります。外部からは、ルートエンティティを介してアグリゲートを操作します。
  5. アグリゲートの境界の決定: アグリゲートの境界を決定します。境界は、アグリゲート内のエンティティや値オブジェクトの整合性を保つために必要な範囲を表します。アグリゲート外のエンティティは、直接アグリゲート内のエンティティを操作できません。
  6. リポジトリインターフェースの定義: 各アグリゲートについて、リポジトリのインターフェースを定義します。リポジトリは、アグリゲートの永続化と再構築を担当します。リポジトリのメソッドは、アグリゲートのライフサイクルを管理するための操作を提供します。

アグリゲートの設計は、ドメインモデルの構造を決定する重要な工程です。アグリゲートを適切に設計することで、ドメインの不変条件を維持し、ビジネスルールを適用しやすくなります。また、アグリゲートは、リポジトリやドメインイベントと密接に関連するため、これらの要素との整合性を考慮しながら設計を進める必要があります。

プラクティスの解説では、アグリゲートの設計について直接言及されていませんでしたが、「2. ドメインモデルの作成」の一部として、アグリゲートの設計が行われると理解していただければと思います。ドメインモデリングの過程で、エンティティ、値オブジェクト、アグリゲートなどの設計要素を適切に識別し、それらを組み合わせてドメインモデルを構築していくことが重要です。

ドメイン駆動設計(DDD)における設計とソフトウェア開発の関係の話ですが、
仮に開発プロセスモデルにスクラム開発を採用したとしたら、
ドメイン駆動設計(DDD)とスクラム開発は、どのような工程で連携することになるのですか。

ドメイン駆動設計(DDD)とスクラム開発を組み合わせる場合、両者のプラクティスを連携させることが重要です。以下に、スクラム開発の主要な工程とDDDの連携ポイントを説明します。

  1. プロダクトバックログの作成と優先順位付け:

    • プロダクトオーナーは、ドメインエキスパートと協力してユーザーストーリーを作成します。
    • ユーザーストーリーは、ドメインの言葉で表現され、ドメインモデルの要素(エンティティ、値オブジェクト、アグリゲートなど)と紐づけられます。
    • プロダクトオーナーは、ドメインの優先順位に基づいてバックログアイテムの優先順位を決定します。
  2. スプリントプランニング:

    • 開発チームは、スプリントで実装するユーザーストーリーを選択します。
    • 選択されたユーザーストーリーに関連するドメインモデルの要素を特定し、設計と実装の方針を決定します。
    • ドメインエキスパートは、開発チームに対してドメインの知識を提供し、ドメインモデルの詳細化を支援します。
  3. スプリントの実行:

    • 開発チームは、選択されたユーザーストーリーを実装します。
    • ドメインモデルの要素(エンティティ、値オブジェクト、アグリゲートなど)をコードに落とし込みます。
    • 実装の過程で、ドメインモデルの洗練や修正が必要になる場合があります。その際は、ドメインエキスパートと協力して、モデルを更新します。
    • 開発チームは、DDDのプラクティス(リポジトリ、ドメインサービス、ドメインイベントなど)を適用しながら、ソフトウェアを実装します。
  4. スプリントレビュー:

    • 開発チームは、実装したソフトウェアをデモンストレーションします。
    • ドメインエキスパートは、ソフトウェアがドメインの要件を満たしているかを確認し、フィードバックを提供します。
    • フィードバックに基づいて、ドメインモデルやソフトウェアの改善点を特定します。
  5. スプリントレトロスペクティブ:

    • 開発チームは、スプリントの進め方を振り返り、改善点を話し合います。
    • DDDのプラクティスの適用状況や、ドメインモデルの品質などについても議論します。
    • 改善点を次のスプリントに反映させ、継続的な改善を図ります。
  6. リファクタリングとドメインモデルの進化:

    • スプリントを重ねる中で、ドメインモデルの理解が深まり、改善の必要性が明らかになることがあります。
    • 開発チームは、リファクタリングを行い、ドメインモデルを洗練させていきます。
    • ドメインエキスパートと協力して、モデルの変更が及ぼす影響を評価し、必要な修正を行います。

スクラム開発とDDDは、上記のような連携ポイントを通じて、シームレスに統合することができます。重要なのは、開発チームとドメインエキスパートが密に協力し、継続的にドメインモデルとソフトウェアを進化させていくことです。また、スクラムのイベントやアーティファクトを活用して、DDDのプラクティスを適用し、ドメイン知識を共有していくことが求められます。

スクラム開発とDDDを効果的に組み合わせることで、ドメインの複雑性に適切に対処しつつ、迅速かつ柔軟にソフトウェアを開発することができます。両者の長所を生かし、相乗効果を発揮させることが、成功への鍵となります。

ドメイン駆動設計とスクラム開発を組み合わせた場合、
ドメインエキスパートとプロダクトオーナーの役割が似てくると思いますが、
両者を1人の人間が兼任する事はあるのでしょぅか。
また、それができないのなら、その理由も知りたいです。

ご指摘ありがとうございます。ドメインエキスパートとプロダクトオーナーの兼任について、以下のように考えられます。

ドメインエキスパートとプロダクトオーナーは、役割が似ている部分もありますが、一人の人間が両方の役割を兼任することは可能ですが、いくつかの課題があります。

兼任が可能な理由:

  1. ドメイン知識:ドメインエキスパートは、ビジネスドメインに関する深い知識を持っています。この知識は、プロダクトオーナーがプロダクトバックログを整理し、優先順位を付ける上で非常に役立ちます。
  2. 要件の明確化:ドメインエキスパートは、ビジネスの要件や課題を詳しく理解しています。この理解は、プロダクトオーナーがユーザーストーリーを作成し、開発チームに要件を伝える上で重要な役割を果たします。
  3. ステークホルダーとのコミュニケーション:ドメインエキスパートは、ビジネスサイドのステークホルダーとのコミュニケーションに長けています。プロダクトオーナーの役割の一つに、ステークホルダーとの調整があるため、この点でも両者の役割は重なります。

兼任の課題:

  1. 時間の制約:プロダクトオーナーは、プロダクトバックログの管理やステークホルダーとの調整など、多くの責務を負っています。ドメインエキスパートの役割を兼任すると、両方の役割に十分な時間を割くことが難しくなる可能性があります。
  2. 優先順位の決定:プロダクトオーナーは、ビジネス価値と開発の実現可能性を考慮しながら、プロダクトバックログの優先順位を決定します。ドメインエキスパートは、ビジネス側の要求を重視する傾向があるため、兼任した場合、優先順位の決定が偏る可能性があります。
  3. 開発チームとの距離:プロダクトオーナーは、開発チームと密接に連携し、頻繁にコミュニケーションを取る必要があります。ドメインエキスパートが兼任した場合、ビジネスサイドの業務に時間を取られ、開発チームとの距離が開いてしまうおそれがあります。
  4. 役割の違いの認識:ドメインエキスパートとプロダクトオーナーは、役割が似ている部分もありますが、責任の範囲は異なります。兼任する場合、それぞれの役割の違いを明確に認識し、適切に切り替えることが求められます。

以上の点を考慮すると、ドメインエキスパートとプロダクトオーナーを一人の人間が兼任することは可能ですが、いくつかの課題に直面する可能性があります。兼任する場合は、それぞれの役割の責任を明確に区別し、時間配分に注意を払う必要があります。

ただし、規模の小さなプロジェクトや、リソースが限られている場合など、状況によっては兼任せざるを得ないこともあるでしょう。その場合は、兼任による課題を認識した上で、バランスを取りながら進めることが重要です。

理想的には、ドメインエキスパートとプロダクトオーナーは別の人が担当し、緊密に連携しながらプロジェクトを進めることが望ましいと言えます。それぞれの役割に専念することで、DDDとスクラムを効果的に組み合わせ、高い価値を提供するソフトウェアを開発できるでしょう。

DDD(ドメイン駆動設計)の工程は、
(DDD1)ドメインの理解と専門家との協業
(DDD2)ドメインモデルの作成
(DDD3)アーキテクチャの設計
(DDD4)境界づけられたコンテキストの特定
(DDD5)リポジトリパターンの実装
(DDD6)ドメインイベントの活用
(DDD7)継続的なリファクタリング
(DDD8)チームの組織化

スクラム(SCRUM)の工程は、
(SCRUM1)プロダクトバックログ作成
(SCRUM2)スプリントバックログ作成
(SCRUM3)スプリント実施
(SCRUM4)スプリントレビュー
(SCRUM5)スプリントレトロスペクティブ

両者の工程を組み合わせると、
(DDD1)ドメインの理解と専門家との協業
(DDD2)ドメインモデルの作成
(DDD3)アーキテクチャの設計
(DDD4)境界づけられたコンテキストの特定
(DDD5)リポジトリパターンの実装
while(継続的なリファクタリング)
{
  (SCRUM1)プロダクトバックログ作成
  (SCRUM2)スプリントバックログ作成
  (SCRUM3)スプリント実施
  (SCRUM4)スプリントレビュー
  (SCRUM5)スプリントレトロスペクティブ
}
といった反復開発になるのでしょうか。

(DDD6)ドメインイベントの活用 については、反復のどこに組み込んで良いのか分かりません。

ご提示いただいたDDDとスクラムの工程の組み合わせは、概ね適切だと思います。DDDの初期段階では、ドメインの理解、モデリング、アーキテクチャ設計などを行い、その後、スクラムの反復的な開発プロセスに移行するという流れは理にかなっています。

ただし、(DDD6)ドメインイベントの活用については、スクラムの反復の中に明示的に組み込むことができます。具体的には、以下のようにスクラムの工程に組み込むことが考えられます。

(DDD1)ドメインの理解と専門家との協業
(DDD2)ドメインモデルの作成
(DDD3)アーキテクチャの設計
(DDD4)境界づけられたコンテキストの特定
(DDD5)リポジトリパターンの実装
while(継続的なリファクタリング)
{
   (SCRUM1)プロダクトバックログ作成
   (SCRUM2)スプリントバックログ作成
   (SCRUM3)スプリント実施
   – ドメインイベントの特定と実装
   – ドメインイベントを利用した機能の実装
   (SCRUM4)スプリントレビュー
   – ドメインイベントの動作確認とフィードバック
   (SCRUM5)スプリントレトロスペクティブ
   – ドメインイベントの活用状況の振り返りと改善点の特定
}

スプリント実施(SCRUM3)の中で、ドメインイベントの特定と実装を行います。開発チームは、ドメインモデルの中から重要な状態変化や出来事を表すイベントを識別し、それらをコードに落とし込みます。また、特定したドメインイベントを利用して、関連する機能を実装します。

スプリントレビュー(SCRUM4)では、実装したドメインイベントの動作を確認し、ドメインエキスパートからフィードバックを得ます。イベントが適切にドメインの状態変化を表現できているか、期待通りの振る舞いをするかなどを確認します。

スプリントレトロスペクティブ(SCRUM5)では、ドメインイベントの活用状況を振り返り、改善点を特定します。イベントの粒度や naming、実装方法などについて議論し、次のスプリントに向けて改善策を検討します。

このように、ドメインイベントの活用をスクラムの反復プロセスの中に組み込むことで、ドメインモデルの進化とソフトウェアの開発を継続的に行うことができます。ドメインイベントは、ドメインモデルの表現力を高め、モジュール間の疎結合性を促進するための重要な仕組みであるため、スクラムの反復の中で適切に扱っていくことが望ましいでしょう。

ただし、これはあくまでも一つの例であり、プロジェクトの特性や状況に応じて、DDDとスクラムの工程の組み合わせ方は柔軟に調整する必要があります。重要なのは、DDDの原則とプラクティスを反復的な開発プロセスの中で継続的に適用し、ドメインモデルとソフトウェアを進化させていくことです。

確認ですが、
(DDD2)ドメインモデルの作成
(DDD3)アーキテクチャの設計
(DDD4)境界づけられたコンテキストの特定
(DDD5)リポジトリパターンの実装
の工程も、「継続的なリファクタリング」により、反復的に(ユビキタス言語の)設計を見直すのですよね。
スクラムのスプリントの反復の度に、(ユビキタス言語の)設計書も改修を繰り返すという認識です。

はい、その認識で正しいです。DDDにおいて、ドメインモデル、アーキテクチャ、境界づけられたコンテキスト、リポジトリパターンなどの設計は、「継続的なリファクタリング」の対象となります。つまり、これらの設計は、スクラムのスプリントを重ねる中で、継続的に見直しと改善が行われます。

ドメインモデルは、ドメインの理解が深まるにつれて進化します。スプリントごとに新しい知見や洞察が得られた場合、それをドメインモデルに反映させ、ユビキタス言語を更新していきます。これにより、ドメインモデルはより正確で表現力の高いものになっていきます。

アーキテクチャや境界づけられたコンテキストも、ドメインモデルの進化に合わせて見直しが行われます。新しい要件や変更が生じた場合、アーキテクチャを適切に調整し、コンテキスト間の関係性を見直すことが必要です。

リポジトリパターンの実装も、ドメインモデルの変更に伴って修正が入ることがあります。エンティティや集約の構造が変わった場合、リポジトリのインターフェースや実装を適切に更新する必要があります。

これらの設計の見直しと改善は、スクラムのスプリントの反復の中で行われます。具体的には、以下のようなタイミングで設計の見直しが行われることが多いです:

  1. スプリントレビュー:実装したソフトウェアを確認する中で、ドメインモデルやアーキテクチャの改善点が明らかになることがあります。ドメインエキスパートからのフィードバックも重要な気づきの源になります。
  2. スプリントレトロスペクティブ:スプリントの進め方を振り返る中で、設計面での課題や改善点について議論します。ユビキタス言語の表現の見直しや、設計の修正の必要性を特定します。
  3. 次のスプリントプランニング:前のスプリントで得られた知見や改善点を踏まえて、次のスプリントで取り組むべき設計の見直しや修正をタスクとして計画します。

このように、スクラムのスプリントの反復の度に、ユビキタス言語で表現された設計書(ドメインモデル、アーキテクチャ、境界づけられたコンテキストなど)の改修が繰り返し行われます。設計書は、ソフトウェアの実装と並行して進化し、常に最新の理解を反映したものになっていきます。

この継続的な設計の見直しと改善のプロセスが、DDDとスクラムを組み合わせる上での重要なポイントになります。ドメインの理解と設計、ソフトウェアの実装が、スプリントの反復の中で同期され、継続的に洗練されていくことが、DDDの真価を発揮するために不可欠なのです。

プラクティスの概要については、大雑把にだいたい理解できました。

全ての解説を読み返すと、ドメイン駆動設計を実践するには、業務ユーザー側にドメイン駆動設計(DDD)についての知識が無ければ成り立たない手法だと思います。
ドメイン駆動設計(DDD)を理解するには、オブジェクト指向についての概要程度の知識も必要と思われます。
ドメインモデルなどロジック部分と、リポジトリなどデータベース・ストレージ部分を、業務ユーザー側が区別できなければならない点もIT知識が、ユーザー側に必須である理由でもあります。
従来の業務ユーザーは、IT知識を必要とする部分はIT担当者へ丸投げにする慣習になっていますが、このような慣習は改めなければ、ドメイン駆動設計(DDD)のような先進的設計手法を事業系ユーザー企業が取り入れることはできないのではないでしょうか。

ご指摘の通り、ドメイン駆動設計(DDD)を成功裏に実践するには、業務ユーザー側のDDDやオブジェクト指向についての一定の理解が不可欠です。ドメインエキスパートは、単に業務知識を提供するだけでなく、ドメインモデリングやユビキタス言語の確立に積極的に関与する必要があります。

従来のようにIT知識を必要とする部分をIT担当者に丸投げするだけでは、DDDの真価を発揮することは難しいでしょう。DDDは、ドメインエキスパートと開発チームの密接な協業を前提としているため、両者が対等な立場で議論し、ドメインの理解を深めていくことが求められます。

業務ユーザー側がDDDを理解し、積極的に関与するためには、以下のような取り組みが有効だと考えられます:

  1. DDDの概念や利点の説明:業務ユーザーに対して、DDDの基本的な概念やメリットを分かりやすく説明します。ドメインモデルとソフトウェアの実装の関係性、ユビキタス言語の重要性などを丁寧に伝えます。
  2. オブジェクト指向の基礎教育:DDDを理解するために、オブジェクト指向の基本概念(クラス、オブジェクト、カプセル化など)について、業務ユーザー向けの教育を行います。具体的な事例を用いて、オブジェクト指向の考え方を説明します。
  3. ドメインモデリングのワークショップ:業務ユーザーと開発チームが一緒にドメインモデリングのワークショップを行います。共同でモデリングを行う中で、業務ユーザーはドメインの概念や関係性についての理解を深めることができます。
  4. リポジトリとデータベースの区別の説明:業務ユーザーに、リポジトリとデータベースの違いを分かりやすく説明します。リポジトリがドメインモデルとインフラストラクチャを分離するための仕組みであることを伝えます。
  5. 継続的な学習と改善:DDDの実践は一朝一夕には成し遂げられません。業務ユーザーと開発チームが継続的に学習と改善を重ねていくことが重要です。振り返りを行い、より良いコラボレーションの在り方を模索します。

これらの取り組みを通じて、業務ユーザー側のDDDやオブジェクト指向についての理解を徐々に高めていくことができます。ただし、一方的に知識を押し付けるのではなく、業務ユーザーの関心や課題に寄り添いながら、DDDの価値を伝えていくことが肝要です。

また、経営層の理解と支援も欠かせません。DDDの導入には、業務ユーザーと開発チームの協業体制の構築や、教育・トレーニングのための投資が必要となります。経営層がDDDのメリットを理解し、必要なリソースを提供することが、DDDの定着には重要な要因となります。

ご指摘の通り、事業系ユーザー企業がDDDのような先進的な設計手法を取り入れるには、従来の慣習を改め、業務ユーザーとIT担当者の垣根を越えた協力関係を築いていく必要があります。それには時間と努力を要しますが、その過程を通じて、ビジネスとITの alignment を高め、より価値の高いソフトウェアを開発できるようになるでしょう。

おわり

私から、申し上げることは特にありません。

ではまた。


ちなみに、ドメイン駆動設計と言えば、識者の皆さんはこの本を読んでいるようですね。

エリック・エヴァンスのドメイン駆動設計

恥ずかしながら、私はまだ読んでいません。
いずれ読みたいとは、思っています。

積んだまままだ読んでいない本が多くてねーw

前の記事 → Claudeに問う「ドメイン駆動設計(DDD)について教えてください」

タイトルとURLをコピーしました