sait0sのブログ

技術で広く浅く遊んでいる、エンジニアの真似事をしている学生です

「エリック・エヴァンスのドメイン駆動設計」を読んだ

 最近、物騒な時代になったなぁと感じます。何か暗いニュースばかりで気分も落ち込みますね。そんなわけで、何かと定期的に炎上するドメイン駆動設計(以下DDD)を読んだので感想とか書いていこうと思います。

対象読者

 UMLとかオブジェクト指向設計は読める、ある程度理解していることが前提になっているので、わからなかったら以下の書籍を読むと良いと思う。UMLオブジェクト指向設計デザインパターンがわかりやすく解説されている。あとは、クリーンアーキテクチャアジャイルプロセスに近いところがあるので、それらを理解しているとより理解しやすいかもしれない。

 

あらすじというか概要

第1部 (1~2章) ドメインモデルを機能させる

1章 知識をかみ砕く

 ドメインの理解者であるビジネスエキスパートとシステムを設計するアーキテクトは、会話を途絶えさせないことが書いてある。綿密にコミュニケーションをして、知識や概念の齟齬がないように努める必要があるとされる。これらの付帯的な方法は、2章へ続いている。

 

2章 コミュニケーションと言語の使い方

 設計、モデリングをする際には、ビジネスエキスパートとアーキテクト間で共通言語を用いることとされる。それが、統一モデリング言語(UML)である。ビジネスエキスパートチームと開発チームで概念が異なる危険性について述べている。例えば、ビジネスエキスパートチームのXXという概念は、開発チームでは△△となっているようなシステムがある場合、翻訳コストだけでなく、ビジネスエキスパートやプログラマーを混乱させる。そうならないために、UMLを用いる。これを貨物輸送システムを例に挙げて説明している。アーキテクトは、ビジネスエキスパートと共にUMLを用いてシステムの設計をしていく。ビジネスエキスパートは理解しているがアーキテクトにわからないこと、アーキテクトは理解しているがビジネスエキスパートにわからないことをお互いに明確にし合う。そこで、システムの隠れた本質を見出していこうとすることが大事である。

 

3章 モデリングと実装を結びつける

 ドメインを基に設計したモノを明示化するのは難しい。そこで、ドメインとモデルを必ず一致させることが重要である。モデリングの際に、UMLを用いてドメインとモデルを一致させるように落とし込む。そうすることで、オブジェクトの責務を明確にし、SOLID原則を順守させる。

 

第2部 (3~7章) モデル駆動設計の構成要素

4章 ドメインを隔離する

 システム開発とはいえ、ユーザからのリクエストを受け取る、DBにアクセスする、レスポンスをユーザへ返すといった単なるデータ処理以外の複雑な処理も実装しなければならない。その解決策として、オブジェクトの責務レイヤー化アーキテクチャを例に挙げている。MVCのようなアーキテクチャフレームワークを用いることで複雑な実装を分割し、開発者はドメインの実装に集中できるという考え方である。凝集度を高めることで、システムとそれ以外を疎結合する。ただし、インフラ層やUI層に悪影響を与える問題もあるが、この後の章に続く。

 

5章 ソフトウェアで表現されたモデル

 モデルをオブジェクトに表現するには、エンティティ(Entity)値オブジェクト(Value Object)サービス(Service)に分けられる。

 Entityの重要なコアは、同一性にある。とあるサービスに登録したBob(男)がいたとすると、Bob(男)という同姓同名はニューヨークにもいるかもしれないし、カルフォルニアにもいるかもしれない。そこで、確実に区別するために顧客IDを用いて識別する。このような、識別IDは外部のモデルと一意になるように識別することもできるし、内部のモデルを区別することもできる。ただし、Entityはimmutableで一意性を担保していく必要がある。

 Value Objectの重要な点は、バリエーションにある。顧客は、ニューヨークに住んでいるかもしれないし、カルフォルニアにも住んでいるかもしれない。しかし、ニューヨークに住んでいる人は1人だけではない。そこで、Entityと一意になるようにモデリングすることでバリエーションを表現できる。Value ObjectはEntityと同様にimmutableである必要がある。

 Serviceは、EntityやValue Objectで表現できないドメインを引き継ぐ。全てのドメインをモデルに押し付けると膨大な責務を持った不自然なオブジェクトが生まれる。ただし、Serviceは独立したインターフェースになるようにUMLの一部となること、状態(Field)を持たせないことが重要である。

 また、パッケージングとモジュールにも注意する。J2EEでは、ビジネスロジックはSession Bean、データアクセスはEntity Beanに集約される。別々のパッケージで構成させるため、コンポーネントが一緒になり実装と関連性を理解することが難しくなる。そこで、フレームワークに依存しない、独立したビジネスモデルを定義することが重要である。ただし、ユビキタスは指針にすること。

 

6章 ドメインオブジェクトのライフサイクル

 複雑なモデルでは、オブジェクトの一貫性を保つことは難しい。ただし、過度なロックを強制すると、相互に干渉し合い、別の問題が発生する。その一例として、DBMSにおけるデッドロックなどがある。そうならないようにするためには、ファクトリ(Factory)リポジトリ(Repository)を用いて集約させる。

 Factoryは、オブジェクトのライフサイクルの過程には複雑な責務が発生するため、クライアントの要求するオブジェクトの生成責務を担うオブジェクトとして用いる。そのため、Factoryはインターフェースを提供することで、クライアントには生成過程のルールや責務を隠蔽できる。ただし、インターフェースの実装については引数や操作は柔軟性が必要である。カタログ商品システムを例に、購入注文と商品のモデルは依存関係がある(購入注文は商品を集約している)。具象クラスではなく、抽象クラスを利用することで依存関係と結合を解消することができる。また、一般的にFactoryは、Entityの条件に一致するものはEntityを、Value Objectに一致するものはValue Objectを生成するが、その使い分けは次のRepositoryへ続く。

 Repositoryは、あらゆるオブジェクトへのアクセスを制限し、オブジェクトが保存されているDBへのアクセスに用いる。Repositoryは、永続化されたオブジェクトを追加・削除するメソッド、属性値の条件に一致するオブジェクトを戻り値として提供することが求められる。ただし、集約ルートから辿れるオブジェクト(Entity)に限定するべきだが、サブセットに複雑なValue Objectoが含まれることもある。その場合は、特定の型として集約させることで対応するまた、Factoryと同様に抽象化させることでアクティブにする。

 

7章 言語を使用する:応用例

 今まで述べてきたことを考慮して、貨物輸送サービスを例にモデリング例を提示している。ここで、重要になるのがルートEntityの抽出である。リレーションされたサブセットを含むモデルを抽出することで、集約されたモデルの境界を引くことができる。

 その一例が荷役イベントである。今までは、予約アプリケーション*1は貨物の予約状況を確認する貨物リポジトリと貨物の予約ができる販売管理システムが両立していたが、同じような責務が混在していた。貨物リポジトリにはquantityBooked(予約状況)、販売管理システムを隠蔽させた配分チェックサービスにderiveEnterpriseSegment(予約したい貨物タイプが適合)とmayAccept(予約済みか判定)で分割することでモデルを維持しつつ、責務を明確に分けたアプリケーションが完成する。

 

第3部 (8~13章) より深い洞察へ向かうリファクタリング

8章 ブレイクスルー

 継続的なリファクタリングは、ときに責務が不明瞭となるブレイクスルーを引き起こす。その例を貸金システムで説明する。

 出資額の上限を規定するファシリティと実際の出資を規定するローンという概念がある。ファシリティの割合によって手数料が決定され、ローンの割合で配当金の受け取り額が変わる。このファシリティとローンはそれぞれ割合が独立して変わる可能性があるときのモデルを考えなければならない。

 

9章 暗黙的な概念を明示的にする

 ドメインの重要な概念を見落としていないか、アーキテクト*2は注意深く議論に耳を傾けなければならない。商業融資アプリケーションを例に利息と手数料に注目する。アーキテクトは利息と手数料の認識を誤解しており、設計していた。そのため、重複した概念や設計になっていたことに気づく。そこで、利息計算における発生主義会計の概念を基に、利息と手数料を完全に分離したリファクタリングができた。ここで重要なことは、概念が明確になるまで何度もモデリングし直すことである。

 一方で、それほど明示的でない概念も存在する。それが制約である。貨物輸送システムを例にすると、貨物予約の際には「貨物の種類ごとに可能な利用しなければならないコンテナの選択」や「優先予約可能貨物の存在」などの制約、いわゆるブッキングポリシーが存在する。ここで、Specificationという概念を用いることで解決していく。このようなビジネスルールは明らかにEntityやValue Objectの責務とは一致しない。そこで、制約の仕様を満たしているか判定するValue Objectを定義する。

class AAASpecification {

boolean isSatisfied(Entity entity) {
return true;
}
}

class BBBSpecification {

boolean isSatisfied(Entity entity) {
return true;
}
}

 こうすることで、ドメイン層から分離させず、EntityやValue Objectの責務から独立したビジネスルールを定義できる。

 

10章 しなやかな設計

 開発者があるコンポーネントを利用するためには、その実装を注視して利用しなければならないときはカプセル化の意義が失われる。そうならないようにするために、クラス操作には効果と目的が明確になる命名して、開発者がすぐに意味を推測できるようにしなければならない。インターフェースの実装を見なければならないようでは、抽象化の効用は限定されてしまう。

 また、どんなに上手く抽象化してもインターフェースが機能別で重複することもある。その場合には、闇雲にクラスやメソッドで分割するのではなく、ドメインや設計に一貫性を持たせて、意図の明確なインターフェースを保つようにすることが重要である。その際に、一つのクラスに対する責務が大きすぎるときは独立したクラスを定義することも検討しなければならない。そして、それらはたいていはプリミティブなものにならないことが多いため、戻り値と引数が同じ型にできる場合はそうするなど依存関係を最小限に留めるようなインターフェースを提供させる。

 一方で、今までの例に挙げた貨物などの用語が関連した他の概念に含まれているかもしれない。その場合は、型レベルで抽象化して宣言的な設計にさせる。

interface Specification {

boolean isSatisfied(Entity entity);
}

class AAASpecification implements Specification {

boolean isSatisfied(Entity entity) {
return true;
}
}

 この他にも、ANDやORといった複雑な仕様や複数の仕様を縫合するような新たな仕様・ビジネスルールを定義することができる。

 

11章 アナリシスパターンを適用する

 ある一定の概念を追跡して重要だと思っていたが、実は本質ではないことがある。その例が、会計アプリケーションにおける勘定科目である。会計において、複式簿記という概念を用いて貸方と借方が一致するようにシステムを設計する。そのため、勘定科目に仕訳記帳を包括することで仕訳記録のすべてを保持し、貸方と借方で対応させようとしていた。しかし、手数料における発生主義という概念を用いることで、勘定科目、仕訳基調、会計取引の重複した概念が取り除かれて洗礼されたモデルになる。

 

12章 デザインパターンをモデルに関係づける

 今まではモデル駆動設計を用いてモデルの問題を解決していたが、デザインパターンを用いることでも解決することができる。StrategyパターンとComposite パターンを用いて説明する*3

 

13章 より深い洞察へ向かうリファクタリング

 問題点を発見することは最も困難であり不確実性も多い。同僚やドメインエキスパートとブレインストーミングすることやアナリシスパターンデザインパターンなどの知識を活用することもできる。モデルを煮詰めることに注力せず、自由な意思決定、スコープと休憩、ユビキタス言語を駆使することで解決策が見いだせることもある。

 また、開発者にドメインの理解が足りていない、設計がよりしなやかになる方法があるなど変更が妥当でない場合は、完全に正当化できるまで待つということも考える。さらに、モデルが突然違うモデルへと代わることもあり得る。このようなブレイクスルーは毎日起こるようなものではないが、そこから新たな好機が生まれることもある。

 

第4部 (14~17章) 戦略的設計

14章 モデルの整合性を維持する

 とあるモデルを用いようとしたら、別のチームで既に使用されていた。2つのチームで異なるモデルを持ちながら、それを認識していないことがあると思いがけない事態を招くかもしれない。

 そこで、境界づけられたコンテキストを用いる。このコンテキストの境界は、チーム編成やアプリケーションの用途、データベーススキーマなどの物理的な観点からモデルの適用範囲を明示的に定義することで、外部からの問題に注意をそらされたり、混乱させることを避ける。ただし、チームが大きく、コンテキストが細かくなるほどモデルが分裂して一貫性を保持することが難しくなる。そこで、モデル同士をユビキタス言語に付け加えることで、コンテキストの境界、議論を明示化することができる。

 その他にも、上流と下流、システム間のモデルに順応させやすくする必要がある。上流と下流で密なコミュニケーションとユビキタス言語を用いた共有によって協力関係を築くこと、2つのシステム間でモデルの関連付けが難しい場合は片方のシステムに寄せるのではなく、腐敗防止層というモデル変換の責務を持たせたインターフェースを用いることも検討するべきである。

 

15章 蒸留

 複雑に混ざり合ったドメインを分離し、知識をモデルに一致させるために蒸留を行う。

 まずは、ドメインモデルの本質であるコアドメインを明確にする必要がある。複雑なシステムや変更が難しいシステムは認識していない重複や誤解が発生する可能性が高く、ビジネスの本質が不明瞭となり道に迷う。そうならないために、大量のモデルからコアドメインを見つけて最も価値のあるものにしなければならない。その際に、コアはできる限り小さくし、コア以外のモデルがコアドメインに与える影響を最小限に抑える。この作業は、長期にわたって参加しているドメインに詳しい開発者とドメインエキスパートに任せる。コアドメインをコントロールするには安定したチームが必要である。

 次に、コアドメインとは直接関係ない要素をサブドメインとして定義する。その際に、高凝集なサブドメインになるようにしなければならない。ドメインの知識とは全く関係ないようなサブドメインに関しては、汎用サブドメインとして外部ライブラリやフレームワーク等に責務を委譲する。

 さらには、モデルの中にはコアとしてだけでなく、サブドメインとしても役割を果たす要素もある。それを隔離されたコアとして分離することでコアの凝集度を高めつつ他のドメインとの結合度を低くする。

 また、コアドメインでさえ多くの詳細を扱っており、サブドメイン間で相互作用があるとモジュール間で多数の参照が発生して分割した意味がなくなる危険性がある。そこで、モデルにおける根本的な概念を抽象クラスやインターフェースに括りだした抽象ドメインを定義する。

 

16章 大規模な構造

 モデルを適切な大きさにモジュール分解しても、巨大なシステムに包括的な原則がないせいで設計全体にどのような役割を果たすか見分けられなくなる。そこで、役割や関係性でパターンを考え出す必要がある。

  • 厳格なルールが支配する設計はモデルに不自然な制約を強いることになるため、大規模なシステムはアプリケーションと共に進化させる
  • 抽象化し過ぎた設計は把握しにくくなるため、そのメタファの中にユビキタス言語を用いてコミュニケーションを行う
  • モデルの依存関係を常に把握し、各モデルとその責務が1つのレイヤに納める
  • 抽象化されたコアを蒸留して、そのインターフェースに様々な実装を置換できるようなフレームワークを作る

このように状況に応じてふさわしいリファクタリングを行う。

 

17章 戦略をまとめ上げる

 今までのプロセスを実行するためには戦略的な設計が必要不可欠となる。

 最初に、戦略的設計の前に、現在の状況を評価する必要がある。

  • コンテキストマップを書く
  • 言語の使われ方、ユビキタス言語でのコミュニケーション
  • コアドメインは識別されているか
  • 使用技術はモデル駆動設計に向いているか
  • チームの開発者は必要な技術スキルを保持しているか
  • 開発者はドメインに関心を持っているか

 アーキテクチャはプロジェクトを通して有機的に成長する。大規模な構造を監督する責任を小さなチームにグループに持たせると構造を維持しやすくなる。そのため、戦略的設計における意思決定を行う才能のある人が少なくともチームに数人はいなければならない。一方で、綿密に強調しているチームが非公式で議論を進め始めることにも注意しなければならない。一方で、意思決定がチームで共有されている場合、何らかの意思決定を中央集権化することが合理的だと判断することがある。ただし、それによってアプリケーションチームの意思決定を妨げないようにする必要がある。

 最後に、評価後の意思決定で以下のことに注意する。

  • 意思決定はチーム全体に伝えなければならない
  • 意思決定プロセスはフィードバックを吸収しなければならない
  • 計画は進化を許容しなければならない
  • アーキテクチャチームが、最も優秀な人材を吸い上げてはならない
  • 戦略的設計にはミニマリズムと謙虚さが必要である
  • オブジェクトはスペシャリストだが、開発者はジェネラリストである
  • 素人にもわかるフレームワークを使用してはならない
  • スタプランに注意すること

 

感想

 読んでみて雑に感想でも書き連ねてみる。

 

ここは同意できる

・エキスパートと開発者で概念を一致させる

 これは、当たり前な気がする。というか、要件定義でこれをやらない人っているんですかね。ビジネスドメインに寄せていくことで設計や実装の本質だと思うし、新たなビジネスを行う際に考慮しなければならない事項が減る。円滑なコミュニケーションを行うためにも、アーキテクトは常にコミュニケーションを図って齟齬をなくす、ドメインをうまくシステムに落とし込むことが重要である。これができない組織は崩壊一直線だと思う。

 

ここは難しい

ドメインモデリングを中心とする設計

 おそらく、ここがDDD vs 非DDDにおける最大の議論の火種だと思う。自分は、どちらかというと非DDD寄りであり、設計はUIやデータに依存すると思っている。まず、ビジネスドメインから設計を考えるということは、顧客が求めるUI(データ)よりもビジネスで必要となるであろうモデル(データ)を定義することを意味している。顧客にとっては、法律だろうが、システム上の制約だろうが関係ない。そんなめんどくさいことを考えずに利用できることの方が重要である。そもそも、UIやデータに依存しない設計なんてできるのだろうか。結局、顧客からのFBでUIやデータを修正しないといけなくなる気もするが、、、 ただ、優先順位の話をどうこうって言いたいわけではなく、顧客(クライアント)の欲しいUI、データが大きくモジュール戦略や設計に関わってくるよねということが言いたい。

 6章や7章においても、集約クラス(Factory, Repository)のパラメータは依存関係にあるため、具象クラスとして結合させる必要はなく、抽象クラスを利用するという考えも不可解に思える。オブジェクトの責務を分割するとは言っても、単にRepositoryなりFactory内でのモデル変換用のモデルを作成しただけな気もする。これが責務の分割と言われても納得できない。

 

 それ以前に許せないのが、矛盾した内容が多いことである。今まで散々、「モデルを定義してオブジェクトと一致させることが重要」、「ユビキタス言語を用いてモデリングと相互理解を深めること」などと散々述べていたのにもかかわらず、「UMLにはこだわらないこと*4としれっと付け加えられている。

早々と落ちが見えてきてしまった感がある、、、

 

・集約の軸としてEntityを定義し、Value Objectはサブセットとして利用する

 DBのテーブル設計で集約したEntity(広義の意味)に他のEntity(広義の意味)がリレーションしていることがよくある。その際に、集約ルートをEntity、その集約に内包された値をValue Objectに定義することが疑問である。コードに表すとこうである。

class OrderEntity {
int id;
ItemVo itemVo;
}

class ItemVo {
int id;
String name;
}

 著書にも書いてあるが、パフォーマンスとのトレードオフである。ここまでしなくても、ベースとなるEntityと判別できるような形で新しいEntityを作成すれば良いかなと思う。

 最近、JavaのORMであるJPAに@OneToManyと@ManyToOneというものが追加されたが、はたして使っている人はいるのだろうか、、、

 

・Frameworkに関して懐疑的な視点を持っている

 2000年代に考察されたものだからか、J2EEなどのWebフレームワークに懐疑的な視点を持っている。確かに、当時のJava界隈は不安定でフレームワークやライブラリ戦略に苦しめられたかもしれない。しかし、今となっては、フレームワークは互換性やレガシー化、エコシステム化を意識して開発されている(はず)。現代において、この考えはもう古い。フレームワークが使い方や実装を強制して、モデル分割やオブジェクトの責務を考慮しなくても良いようになっている。ただし、著者はフレームワークを直接的に否定しているわけではない。あくまで「フレームワークによってモデル分割が不可解なものになっては意味がない」程度にとどめている。そこを敢えてフレームワークに依存しないと誤認してしまう人もいるのではないかとも思って付け加えた。

 

・ビジネスルールをビジネスロジックから分離させる

 自分は、ビジネスロジックの中にビジネスルールを定義するべきだと感じている。DDDにおけるドメイン層がどの範囲までなのかはわからないが、ビジネスルールを独立させること自体は危険に感じる。再利用可能性は高まるかもしれないが、権限や機能ごとにビジネスルールが異なると意味がないものになってしまうし、ビジネスルールなValue Objectが量産されかねない気がする。

 例えば、ルールA, B, C, D, E... とあり、△△の条件ならAとBとCを、XXの条件ならAとDとEを... みたいな条件によって適用されるルールが異なるのであれば有効だとは思うし、それなら自分もそうする。ただ、弊社のシニアアーキテクトにも聞いたが、「そんな複雑なビジネスルールが存在するシステムはないし、UX視点からも良くないでしょ」と一蹴されてしまった、、、

 

・コアドメインへの定義

 コアドメインを明確に定義は理想的ではあるが、実際にはかなり難しいと思う。抽象ドメインという選択肢が残されているようにどうやっても多くのドメイン知識を持つ汎用コアドメインになりかねない気がする。それほどドメインを定義することは難しい。また、コアドメインを蒸留したとしても、ビジネスの変化が激しければコアドメインに変更が絶対的に起こらないとは限らないはずである。どちらにしても、解決策がリファクタリングモデリングし直すしかなく、リファクタリングのためのリファクタリングと現実的な解決策ではない。また、コアドメインへの蒸留に関しても、長期にわたって参加しているドメインに詳しい開発者を中心にすることも良くない気がする。DDDの文化を培ってきたのであれば可能かもしれないが、基本的にモデリングや設計に携わったことがない人に任せるのはかなりの勇気のいる選択だと思う。さらに、安定したチームであることが前提であり、その人が転職せずに残っているとは限らない、、、(属人的でもある)

 

それ以外で

・DDDは逆コンウェイドメインに理解がないのはコンウェイだから

 このような意見ってどこから来たんでしょう。開発者にもドメインに関心を持たせる、採用でスクリーニングするとは書かれていたけど、コンウェイや逆コンウェイは全く書かれていない。14章の最初だけを読むと、逆コンウェイ戦略をとっているようにみえるが、14~15章を通して読んでみると、あくまでモデルを維持するためであって、アーキテクチャや設計のための組織を作ると伝えているわけではないと感じた。その結果の副作用が、逆コンウェイ戦略ということだと思う。

 あとは、コンウェイだろうが、逆コンウェイだろうがドメインに理解がないと設計すらできないと思うが、、、

 それ以上に、まさに外部因子を排除して、その組織(コンテキスト)内で完結するようなコンテキストの境界を定義する*5と書かれている時点で、かなりの違和感を感じた。「外部とのコミュニケーションを諦めて、Closedな組織にしましょう!」と言っているようなものである。自分は同意できない。

 言わずと知れた名著である「イノベーションのジレンマ」にて、コンピュータ業界におけるイノベーションの失敗について以下のように書かれている。

たいてい製品開発組織は部品ごとにサブグループごとに分かれているため、企業の組織構造は、部品レベルのイノベーションを促すことが多いとされている。製品の基本的なアーキテクチャーを変更する必要がなければ、このようなシステムは効果的である。しかし、アーキテクチャーの技術革新が必要な場合には、人々とグループが新たな方法でコミュニケーションをとり、連携して働く必要のあるイノベーションにとって、このような組織構造が妨げになるという。

(中略)

組織の構造と、組織を構成するグループは、その組織の主要製品を設計しやすいように作られているかもしれず、因果関係の方向が逆転することもありえる。その場合、組織の構造と、更生されるグループの関係は、新製品の設計能力に影響を与えかねない。

 

(注)ここでのアーキテクチャーは、コンピューターアーキテクチャの意である

イノベーションのジレンマ」2章 p60

 まずは、コンウェイだの逆コンウェイだの言う前に、サブグループで境界のない、連携しやすい組織構造への改革が今まさに必要だと感じている。ただし、各サブグループが独立していることが悪いと言いたいわけではない。デプロイ頻度とか生産性の向上は一定程度見込むことができる。ただ、コンポーネントレベルの変更だけ対応できれば良い状況(もしくは、その適用範囲を超えたことはやらない状況)を許容していること、開発者のためだけの設計・組織構造に陥る可能性が非常に高いことを危惧している。それでは、本末転倒だよねということが言いたい。そういう意味では、イーロンマスクのコミュニケーション施策は的を射ていますね。

 あとは、この記事にもある通り、コンウェイや逆コンウェイってもう古い気がします。変に組織論とかイノベーションとか言っている人ほど組織構造に名付けたがったり、境界を引きたがるのかもしれない、、、 (すごく、自分の言いたいことがまとまっている)

future-architect.github.io

 

・DDDはコミュニケーション手法

 はたしてそうだろうか、、、 まず、本書のドメインエキスパートとアーキテクトの会話を見るとわかるが、アーキテクトがドメインエキスパートにユビキタス言語を用いてモデリングの議論をしている。ドメインエキスパートが設計やモデリングに詳しいとは限らないし、こういうモデルにしたら機能的にどうなるというのは全く興味ないと思う。確かに、経営者にもITやソフトウェアエンジニアリングに理解を持たせることは必要だが、これらに理解がない時点でIT企業の経営者に向いていないのでそれ以前な問題な気もする。

 経営者以外でいうと、開発者同士でシステムのモデリングすることについても考える。ER図だのユースケース図だのは書くことがあっても、ユビキタス言語やUML図でのシステムモデルを表現することはあるのだろうか。(ここは、自分自身が経験していないのでわからないので何とも言えない、、、)

 どちらにせよ、概念に齟齬のないように常にコミュニケーションをとるというのは当たり前であって、システムモデリングをコミュニケーション手法とは言わないと思う、、、

 

オブジェクト指向論争

 ここまで、DDDを含めたオブジェクト指向の議論がめんどくさいと脱オブジェクト指向の流れも頷ける。ただ、実際には難しい。JavaC#C++で作られた膨大なエコシステムと資産はオブジェクト指向があったからこそであり、エコシステムや資産の少ない他の言語を採用するのはかなりのチャレンジだと思う。あと、その言語らしい設計をするべき意見もあるが、その言語らしいって何をもって言うのだろう、、、

最後に

 完全に、DDDを否定する人みたいになってしまったが、自分は実現できれば理想だと思う。ただ、もう少し議論の余地があるし、多くの人を納得させるまでには至ってないとも感じる。やはりどうしても「組織規模が小さければ」とか「ドメインが単純なものであったら」と思ってしまう。単なるアーキテクトが、「じゃ、DDDやりましょう!」と言ってできるものでもないし、組織レベルから抜本的に変えていかなくてはならない。

 つまり、取り入れられることもあるし、難しいこともあるというのが自分の意見である。それはどの議論においても同じことなのでトレードオフ。どこを取捨選択するかで使い分ければ良いのかなと思った。

*1:本書では、アプリケーションと書かれているが、機能と同義である

*2:本書では、開発者と書かれているが今までの表記に則りアーキテクトと表現する

*3:本書では、デザインパターンの詳細は触れられていないため別途参照を推奨する

*4:5章 p119

*5:14章 p344