エリック・エヴァンスのドメイン駆動設計を読みました③

前回の投稿

■蒸留
蒸留とは混ざり合ったコンポーネントを分離するプロセス。
モデルとは知識が蒸留されたもの。
今までの章で行ってきたドメインモデルの洗練も蒸留ではあると思いますが、この本の15章の蒸留はここまで洗練してきたドメインモデル群を更に大事なものから優先順位をつけて分離していくことを言っていると思います。
この蒸留の目的は、システム内で最大の価値を付加すべきものをたった1つ抽出すること。
抽出されたものがコアドメイン。
そのコアドメインは当然我々のソフトウェアを特徴づけ、構築する価値のあるものにする。
化学の蒸留と同様に、蒸留プロセスにおいて分離されたかなり価値がある副産物(汎用サブドメインなど)が出来上がる。

・コアドメイン
ドメインに関心があって技術的にも優秀なメンバーがコアドメインに当たるべきとのこと。
ただ技術的に優れていてもドメインに関心がない人が多い傾向にあるためなかなかそんな人はいない。
ただそういう場合はドメインに関心がある優秀なメンバーを集め、ドメインエキスパートが参加するチームを収集し補佐する。
コアドメインの選択はその「システム内で最大の価値を付加すべきもの」なので、システムによって様々。

・汎用サブドメイン
システムを機能させて、モデルを完全に表現するためには欠かせないもので補佐役を果たす。
相当数のビジネスで必要になる概念を抽象化している。
例としては、企業の組織図、財務に関するもの、タイムゾーンなど。

汎用という言葉があるがこれはコードが再利用可能ということではない。
再利用性を考慮していては、蒸留のコアドメインに集中するという動機から外れてしまう。
汎用的な概念の範囲内に収めるということには集中する。

・ドメインビジョン声明文
コアドメインとそれをもたらす価値に関する簡潔な記述を作成する
チームに共通の方向性を与える。
新しい洞察を得たら改訂すること。
ドキュメントって最初は気合い入れて作るけど、改訂を怠りがちになりますよね。。。

・強調されたコア
ドメインビジョン声明文は広い観点から見たコアドメインを識別するもの。
強調されたコアは具体的なコアドメインの要素の識別をするための文書。
これがないと個人の解釈によって識別することになってしまうため、好ましくない。
記述方法として「蒸留ドキュメント」や「コアにフラグを立てる」というものがある。
蒸留ドキュメントはコアドメインとコアを構成する要素間の主要な相互作用を簡潔に記述する。
コアにフラグを立てるというのはUML図などでコアとなる要素に印をつけておくこと。

・凝集されたメカニズム
オブジェクト思考設計にとってカプセル化は標準的なプラクティス。
「何が」(what)と「どのように」(how)を分離するが、「何が」(what)が、「どのように(how)」によって肥大化し、複雑化することがある。問題を解決するためのアルゴリズムが多くなって問題を表現するメソッドがわかりにくくなる。
こういうことが多くなってきたらモデルに問題がある兆候。
この問題を解決するためのアルゴリズムなどを概念的に凝集された部分を切り分けて、フレームワーク化する。

汎用サブドメインも凝集されたメカニズムもコアドメインの負担を軽減したいという願望に基づいているが、汎用サブドメインは表現力豊かであるモデルで、凝集されたメカニズムはドメインを表現しない。
モデルにより提起された面倒な処理の問題を解決するためにある。

・隔離されたコア
モデルをリファクタリングして、補助的な役割を果たすものから分離すること。
そうすることで凝集度が高まり、他のコードへの結合が低くなる。

隔離するために

  1. コアサブドメインを識別する
  2. 関連するクラスを、それに関係づけている概念に由来する新しいモジュールへ移動する。
  3. コードをリファクタリングして、概念を直接表現していないデータと機能を切り離す。
  4. 他のモジュールとの関係を最小限におさえて明確化する。
  5. 1から繰り返す

・抽象化されたコア
モデルにおけるもっとも基本的な概念を識別し、それを別のクラス、抽象クラスまたはインターフェースに括り出す。
この抽象的なモデルは、重要なコンポーネント間をほとんど表現するように設計する。
この抽象的なモデル全体を独自のモジュールに入れる。
ただし、特殊で詳細な実証クラスは、サブドメインによって定義されたモジュールに残す。

■大規模な構造
ようやく森を見る。
森を見るためにそれぞれの木の役割や関係性を明確にしておく。
概念上の大規模な構造をアプリケーションと共に進化させ、場合によって、全く別の種類の構造に変更する。
大規模な構造は一般に、境界付けられたコンテキストを横断して適用できる必要があり、現実の制約にも対応しなければならない。

大規模な構造を適用すべきなのは、モデルの開発に不自然な制約を強いることなく、システムを大幅に明確化する構造が見つけられたときでうまくいかなければ別になくてもよい。

・責務のレイヤ(システムのメタファ、知識レベル、着脱可能なフレームワークは略)
責務駆動設計は大規模な構造に対しても適用される。
責務駆動設計と同じように、上位層は下位層に依存するが、下位層は上位層からは独立するような形。
レイヤ化すると見通しがよくなるかもしれない。
過度なレイヤ化は逆にわからなくなるので注意。
モデルの依存関係を調べ、ドメインに自然な階層が認められたら責務を与える。

■感想
2019年12月、自分は初めてPHPカンファレンスに参加しました。
その初ペチコンで初めて受講した講義が、

MVCにおける「モデル」とはなにか
https://fortee.jp/phpcon-2019/proposal/b6302d4a-a8b8-41a7-ad0c-98704fd18c6c

でした。
正直内容が難しく、後々の講義もこのレベルが続くのか…と絶望していました。
後々、参加者の感想を見ると熟練者の方でもこのトークは難しいレベルだったみたいです。

ただ今回、当時のトークで

(飲食店等において)
ホールの人は「客とオーダーが満たされているか」が関心事であり、
キッチンの人にとっては「料理をどの順番で提供しなければならないかが関心事」

と聞いたことを思い出し、この関心事に注目してモデリングすべきなんだと本を読みながら感じることが出来ました。
誰にとっては何が値オブジェクトで何がエンティティなのかとかですね。
当時わからなかったことが少しでもわかるようになったのは嬉しかったです。

設計の本を読むとプログラマに最も必要なのはコミュ力ではないかと思ってきますね。

どうしてコミュ障に優しい世界じゃないんですか…?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です