Learning Domain Driven Design - 11. Evolving Design Decisions
競争に追いつくためには、企業は絶えず変化、進化する必要がある
プロジェクトをとりまく環境の変化が設計にどう影響するか、どうやって進化させていくか議論していく
ドメインの変更
Core: 競合とは異なり、優位性になる
Support: 競合とは異なる方法だが、優位性にはならない
Generic: すべての企業が同じ方法で行う
ビジネスドメインのニーズに適用するソフトウェアを設計するには上記を識別することが非常に重要
しかしそれだけではなく、サブドメインの進化に注意を払うことも同じくらい重要
Core to Generic
オンライン小売会社のBuyITが独自の注文配送ソリューションを実装していると想像してください。それは配達ルートを最適化するための革新的なアルゴリズムを開発し、その結果、競合他社よりも低い配達料金を請求することができました。ある日、DeliverITという別の会社が配達業界を変革しました。それは「巡回セールスマン」の問題を解決し、サービスとしての経路最適化を提供していると主張しています。DeliverITの最適化はさらに進んでおり、BuyITが同じタスクを実行するためのコストの一部で提供されています。BuyITの視点から見ると、DeliverITのソリューションが既製品として利用可能になったとき、そのコアサブドメインはジェネリックサブドメインに変わりました。その結果、最適なソリューションがBuyITのすべての競合他社に利用可能になりました。研究開発への大規模な投資なしに、BuyITは経路最適化サブドメインで競争上の優位性を得ることはできません。以前はBuyITの競争上の優位性と見なされていたものが、その競合他社すべてに利用可能な商品になりました。
Generic to Core
BuyITは、その成立以来、在庫を管理するための既製のソリューションを使用してきました。ただし、そのビジネスインテリジェンスレポートは、顧客の要求の予測が不十分であることを継続的に示しています。その結果、BuyITは最も人気のある製品の在庫を補充することができず、人気のない製品に倉庫の土地を無駄にしています。いくつかの代替在庫管理ソリューションを評価した後、BuyITの経営陣は、設計および構築のための戦略的な決定を下すことにしました。この社内ソリューションは、BuyITが販売する製品の複雑さを考慮し、顧客の要求の予測をより正確に行います。既製のソリューションを独自の実装で置き換えるというBuyITの決定により、在庫管理はジェネリックサブドメインからコアサブドメインに変わりました。機能の成功した実装により、BuyITは競合他社に追加の競争上の優位性を提供します。競合他社はジェネリックソリューションで「立ち往生」しており、BuyITが発明および開発した高度な需要予測アルゴリズムを使用することはできません。ジェネリックサブドメインをコアサブドメインに変える会社の実際の教科書の例はAmazonです。すべてのサービスプロバイダーと同様に、Amazonはそのサービスを実行するためのインフラストラクチャが必要でした。同社は、物理的なインフラストラクチャの管理方法を「再発明」することができ、後にそれを利益を上げるビジネス、Amazon Web Servicesに変えました。
Support to Generic
BuyITのマーケティング部門は、取引先およびその契約を管理するためのシステムを実装しています。このシステムには特別または複雑なものはありません。データを入力するためのいくつかのCRUDユーザーインターフェイスです。言い換えれば、それは典型的なサポートサブドメインです。ただし、BuyITが社内ソリューションの実装を開始してから数年後、オープンソースの契約管理ソリューションが登場しました。オープンソースプロジェクトは、既存のソリューションと同じ機能を実装しており、OCRや全文検索のようなより高度な機能を持っています。これらの追加機能は、長い間BuyITのバックログにありましたが、そのビジネスへの影響が低いため、優先されることはありませんでした。したがって、同社は社内ソリューションを捨ててオープンソースソリューションを統合することを選択しました。その結果、ドキュメント管理サブドメインはサポートからジェネリックサブドメインに変わりました。
Support to Core
サポートサブドメインはコアサブドメインに変わることもあります。たとえば、会社がサポートロジックを最適化する方法を見つけ、それによってコストを削減するか、追加の利益を生み出す場合です。そのような変換の典型的な症状は、サポートサブドメインのビジネスロジックの複雑さが増加していることです。サポートサブドメインは、定義上、シンプルであり、主にCRUDインターフェイスまたはETLプロセスに似ています。ただし、ビジネスロジックが時間の経過とともに複雑になる場合、追加の複雑さの理由があるはずです。それが会社の利益に影響を与えない場合、なぜそれがより複雑になるのでしょうか?それは偶発的なビジネスの複雑さです。一方、それが会社の収益性を向上させる場合、それはサポートサブドメインがコアサブドメインになっている兆候です。
Core to Support
コアサブドメインは、時間の経過とともにサポートサブドメインになることができます。このようなことが起こるのは、サブドメインの複雑さが正当化されない場合です。言い換えれば、それは利益を上げていません。そのような場合、組織は余分な複雑さをカットすることを決定し、他のサブドメインの実装をサポートするために必要な最小限のロジックを残すことができます。
Generic to Support
コアサブドメインと同じ理由で、ジェネリックサブドメインはサポートに変わることができます。BuyITのドキュメント管理システムの例に戻ると、同社はオープンソースソリューションの統合の複雑さが利益を正当化しないと判断し、社内システムに戻ることを決定しました。その結果、ジェネリックサブドメインはサポートサブドメインに変わりました。
https://gyazo.com/269ed7cb60d1ed44d97b784518edc7d7
戦略的設計への影響
to Core
もともと複数のチームで機能を複製していた場合は統合するべき
Core はドメイン知識の情報源にできるだけ近い場所で、社内で実装する必要がある
Support to Core の場合は実装を社内に移動する必要が出てくる
Core to Support
他の Core に集中するために実装をアウトソースすることができる
戦術的設計への影響
Support は比較的シンプルな設計パターン(Transaction Script, Active Record)で実装されるが、複雑なルールや不変性の追加に対応していない。新しい機能を追加するのには痛みを伴う。
ビジネスドメインの変化に伴い適切な設計に進化させていく必要がある
Transaction Script to Active Record
データの操作が複雑になってきた場合その部分を Active Record にリファクタする
複雑なデータ構造をカプセル化していく
Active Record to Domain Model
ビジネスロジックが複雑になったり、一貫性や重複を考慮することなどが増えてきた場合 Domain Model にリファクタする
どのデータ構造を不変のオブジェクトとしてモデル化できるか探す
データ構造をみてトランザクションの境界を探す
Active Record の setter を全て private に変更し、変更は明示的なメソッドからのみ行えるように
Domain Model to Event-Sourced Domain Model
適切な設計された集約境界を持っている Domain Model は移行できる
データを直接変更するのではなく、ドメインイベントをモデル化する
過去のイベントは存在しないので、最善の努力で過去のイベントを生成する or 移行用のイベントを用意する必要がある
組織の変化
組織の構造の変化は、チームのコミュニケーションや協力のレベルに影響を与える
その結果境界づけられたコンテキストの統合方法に変化を与えることがある
e.g.
人数が増えてチームを分割する
チームの場所が物理的に遠い場所になった
顧客とのパートナーシップ関係が、サプライヤー関係になった
ドメイン知識
モデリングは継続的なプロセスである
多くの場合ドメインの複雑さは暗黙的。初めはシンプルに見えるが、次第に機能追加していったりするうちに多くのエッジケースやルールが発見されていく
これはしばし破壊的な変更であり、最初から再構築する必要があることも
そのため、ドメインロジックが不明瞭で頻繁に変更される場合は、境界づけられたコンテキストを広い境界で設計することが理にかなっている。
時間が立ってドメイン知識が溜まってくると、少しずつ設計をアップデートしていき適切な境界を見つけられるようになる
また、ドメイン知識は時間が経つと失われていく
ドキュメントが古くなったり、人がいなくなったり
ドメイン知識の劣化を積極的に防ぐことは非常に重要。それを回復するための効果的なツールとして、 EventStorming ワークショップ (次章で紹介) がある
グロース
新しい機能が継続的に追加されているのはシステムが成功している兆候。ユーザーに価値をもたらし、拡張されていく。しかし成長につれてコードベースは巨大な泥の塊になっていくことがある
グロースはコンポーネントの境界を吹き飛ばし、機能を増加させ続けていく
成長に応じて、これまで決定してきた設計について再度評価し続けることが重要
最初からドメインの境界など完璧なものを目指すのは難しいので、有用な境界を目指すこと
たとえば、境界づけられたコンテキストがますます ”おしゃべり" になっていくことに気づくかもしれないが、それは効果的でないことの良い兆候
まとめ
競争力を維持するため、企業は常に進化していく必要がある
ビジネスドメインが進化するにつれて、そのサブドメインの変化を特定し、設計を見直していくこと
過去の設計に関する決定が、現在のビジネスドメインの状態と一致していることを確認する
必要に応じてより適合するように進化させていく
ビジネスドメインについての学習は継続的なプロセスであり、多くのドメイン知識が発見されるにつれて、設計を進化させていく必要がある
より良い設計を行うために、集約の境界が特定の問題解決にフォーカスしていることを確認し、できるだけ小さくすること
偶発的な複雑さを排除し、ビジネスドメインの本質的な複雑さを管理していくこと