ドメイン層で、if 文や、for 文がぐちゃっと、書かれた部分を見つけたら、たぶん、Cohesive Mechanizms パターンの出番。
ドメインモデルの中で、if 文や for 文がごちゃごちゃ書かれている部分を、うまく括りだして、パッケージやクラスにすると、ドメインモデルの見通しがよくなるよ、というパターン。
for 文がぐちゃっと書かれている場合、モデルとしては、ツリー構造や、グラフ(node と edge ) 構造で、情報を扱っていることが多い。
Domain-Driven Design(DDD) では、例として、
・組織階層
・輸送経路
を扱う業務を取り上げている。
組織の「指揮・命令系統」「報告先」とか「責任・権限」とかが、ツリー構造になっている。
LDAP などは、こういう構造を扱えるツール。
業務アプリだと、所属部門とか、上司、上位部門とかを特定したいことがよくわる。
こういう時、ツリー構造になっている、オブジェクト階層から、必要な情報を得るアルゴリズムは、for 文とか、 if 文で、ごちゃごちゃ書く羽目になる。
こういう「ツリー」を扱う、アルゴリズムは、ひとかたまりのパッケージやクラスにカプセル化しちゃえば、コードがかなりすっきりする。
内部の複雑な処理を、まったく意識せずに「上司」を取り出すメソッドとか使えるので、使う側のコードが、シンプルになる。
どの経路をたどるのが、一番、時間が短いか?、一番安いか?という、いわゆる「経路探索」問題ですね。
「乗換案内」サービスが、まさにこれ。
使う側は、中身のデータ構造とか、アルゴリズムなんか意識しないで、「渋谷からディズニーランド」までの最短経路は?という問い合わせをすれば、時間順、コスト順とかで候補が、表示される。
グラフ構造は、汎用的なモデルで、どんなモデルも、グラフで表せちゃう。
「ネットワークモデル」とも言うのかな。
プロジェクトの管理も、「タスク・ネットワーク」として、タスクの依存関係とか、クリティカルパスの検出とかに、グラフ構造と、アルゴリズムを使っている。
業務アプリをやっていると、限定的だけど、ツリー構造とか、グラフ構造とかと、(無意識に)戦っていることがあるんですよね。
複雑な条件マッチングとかは、DDD の Specifcation パターンが、 Cohesive Mechanism として使えるかもしれない。
興味があれば、私が前に書いた、 Specification パターン : 複雑なビジネスルールの表現手段 を読んでみてください。
if 文や for 文がぐちゃっとしていたら、Cohesive Mechanism の可能性が大きい。
もっとも、まず、初歩的な関心事の分離がでてきることが前提。
データベースの検索結果( record set ) を、自分で、for 文で処理するようなコードを書いていたら、それは、Cohesive Mecanisms パターンの対象ではない。
こういう部分は、データアクセスや O-R マッピングのフレームワークに任せるに限る。
あと、Collection フレームワークをきちんと理解して、使いこなすことも、基本中の基本。
たとえば、 List から、重複を除いて、ユニークな要素の集合が必要なら、 List から Set をコンストラクトすれば、以上終了。 for 文なんて、一切不要。
SQL だと、DISTINCT 句ですね。
Set は、もちろん、和集合とか差集合とか演算メソッドもある。
SQL の UNION とか、MINUS とかですね。
Java だと、Collections クラスの static はメソッド群は、一通り勉強しとかなきゃね。
List をランダムに並べ替えたい、というニーズがあったとき、乱数生成と for 文で力づくで書きはじめちゃった奴がいた。
あわてて、 Collections#shuffle を使うようにアドバイス。どうして、for 文 書きたがるかなあ?
Collections クラスは、逆順の並べるとか、不変コレクションの作成とか、コレクション間の演算とか、ほんと、便利なツール。
List, Set, Map, Collections に習熟して、データアクセスとかは、フレームワーク使えば、ドメイン層で、 for 文を書く必要は、激減する。
コレクションフレームワーク、永続化フレームワークをちゃんと使いこなせば、ドメイン層からは、for 文は激減します。
それでも、for 文と if 文で、なにか処理したいたら、それは、ツリー構造かグラフ構造(の部分的な問題)を扱っているのかもしれない。
こういう場合、まず
・使い側にとって都合の良い
・意味のわかりやすい
インタフェースを宣言しちゃう。
そして、for 文とか、データ構造やアルゴリズム側は、インタフェースの中に隠蔽してしまう。
これが、Cohesive Mechanisms パターン。
Cohesive Mechanisms パターンで、設計・実装したパッケージやクラスは、たいていは、プログラミングの処理手続きで、ドメインの中核の問題や知識でない。
私のたちの経験した中では、「仕事」と「希望条件」のマッチングアルゴリズムが、Cohesive Mechanism で、かつ、Core Domain (問題の核心、価値の源泉)というケースがあった。
でも、そんなにしょっちゅうあることではない、と思う。
Generic Subdomains パターンと、 Cohesive Mechanisms パターンを適用すると、ドメインモデルの見通しがよくなってくる。
パターンの適用前は、ドメインモデルは、「オブジェクトの海」になっていて、いろいろなオブジェクトが、構造もなく、広がっているように見える。
その中から、 Generic SubDdomains や、Cohesive Mechanisms を抽出 ( Distillation ) して分離する。
そうすると、分離して残ったものが、もう少し、濃厚な概念を持った状態になり、また、構造らしきもの、核の候補とかが見つけやすくなってくる。
楽観的なケースだと、Generic Subdomains と Cohesive Mechanisms を見つけて、分離しちゃうと、残ったものが、 Core Domain モデルの初期バージョン、ということだってありそう。
もちろん、
・Generic Subdomains の引き出しを多く持っていること
・コレクションフレームワーク、永続化フレームワークを適切に使っていること
が前提ですね。
ドメインモデルの中で、if 文や for 文がごちゃごちゃ書かれている部分を、うまく括りだして、パッケージやクラスにすると、ドメインモデルの見通しがよくなるよ、というパターン。
ツリー構造、グラフ構造
for 文がぐちゃっと書かれている場合、モデルとしては、ツリー構造や、グラフ(node と edge ) 構造で、情報を扱っていることが多い。
Domain-Driven Design(DDD) では、例として、
・組織階層
・輸送経路
を扱う業務を取り上げている。
組織(ツリー構造)
組織の「指揮・命令系統」「報告先」とか「責任・権限」とかが、ツリー構造になっている。
LDAP などは、こういう構造を扱えるツール。
業務アプリだと、所属部門とか、上司、上位部門とかを特定したいことがよくわる。
こういう時、ツリー構造になっている、オブジェクト階層から、必要な情報を得るアルゴリズムは、for 文とか、 if 文で、ごちゃごちゃ書く羽目になる。
こういう「ツリー」を扱う、アルゴリズムは、ひとかたまりのパッケージやクラスにカプセル化しちゃえば、コードがかなりすっきりする。
内部の複雑な処理を、まったく意識せずに「上司」を取り出すメソッドとか使えるので、使う側のコードが、シンプルになる。
経路(グラフ構造)
どの経路をたどるのが、一番、時間が短いか?、一番安いか?という、いわゆる「経路探索」問題ですね。
「乗換案内」サービスが、まさにこれ。
使う側は、中身のデータ構造とか、アルゴリズムなんか意識しないで、「渋谷からディズニーランド」までの最短経路は?という問い合わせをすれば、時間順、コスト順とかで候補が、表示される。
グラフ構造は、汎用的なモデルで、どんなモデルも、グラフで表せちゃう。
「ネットワークモデル」とも言うのかな。
プロジェクトの管理も、「タスク・ネットワーク」として、タスクの依存関係とか、クリティカルパスの検出とかに、グラフ構造と、アルゴリズムを使っている。
業務アプリをやっていると、限定的だけど、ツリー構造とか、グラフ構造とかと、(無意識に)戦っていることがあるんですよね。
Specification パターン
複雑な条件マッチングとかは、DDD の Specifcation パターンが、 Cohesive Mechanism として使えるかもしれない。
興味があれば、私が前に書いた、 Specification パターン : 複雑なビジネスルールの表現手段 を読んでみてください。
if 文 や for 文
if 文や for 文がぐちゃっとしていたら、Cohesive Mechanism の可能性が大きい。
もっとも、まず、初歩的な関心事の分離がでてきることが前提。
初歩的な関心事の分離
データベースの検索結果( record set ) を、自分で、for 文で処理するようなコードを書いていたら、それは、Cohesive Mecanisms パターンの対象ではない。
こういう部分は、データアクセスや O-R マッピングのフレームワークに任せるに限る。
あと、Collection フレームワークをきちんと理解して、使いこなすことも、基本中の基本。
たとえば、 List から、重複を除いて、ユニークな要素の集合が必要なら、 List から Set をコンストラクトすれば、以上終了。 for 文なんて、一切不要。
SQL だと、DISTINCT 句ですね。
Set は、もちろん、和集合とか差集合とか演算メソッドもある。
SQL の UNION とか、MINUS とかですね。
Java だと、Collections クラスの static はメソッド群は、一通り勉強しとかなきゃね。
List をランダムに並べ替えたい、というニーズがあったとき、乱数生成と for 文で力づくで書きはじめちゃった奴がいた。
あわてて、 Collections#shuffle を使うようにアドバイス。どうして、for 文 書きたがるかなあ?
Collections クラスは、逆順の並べるとか、不変コレクションの作成とか、コレクション間の演算とか、ほんと、便利なツール。
List, Set, Map, Collections に習熟して、データアクセスとかは、フレームワーク使えば、ドメイン層で、 for 文を書く必要は、激減する。
ドメイン層で for 文を見つけたら
コレクションフレームワーク、永続化フレームワークをちゃんと使いこなせば、ドメイン層からは、for 文は激減します。
それでも、for 文と if 文で、なにか処理したいたら、それは、ツリー構造かグラフ構造(の部分的な問題)を扱っているのかもしれない。
こういう場合、まず
・使い側にとって都合の良い
・意味のわかりやすい
インタフェースを宣言しちゃう。
そして、for 文とか、データ構造やアルゴリズム側は、インタフェースの中に隠蔽してしまう。
これが、Cohesive Mechanisms パターン。
Cohesive Mechanisms パターンで、設計・実装したパッケージやクラスは、たいていは、プログラミングの処理手続きで、ドメインの中核の問題や知識でない。
私のたちの経験した中では、「仕事」と「希望条件」のマッチングアルゴリズムが、Cohesive Mechanism で、かつ、Core Domain (問題の核心、価値の源泉)というケースがあった。
でも、そんなにしょっちゅうあることではない、と思う。
効用
Generic Subdomains パターンと、 Cohesive Mechanisms パターンを適用すると、ドメインモデルの見通しがよくなってくる。
パターンの適用前は、ドメインモデルは、「オブジェクトの海」になっていて、いろいろなオブジェクトが、構造もなく、広がっているように見える。
その中から、 Generic SubDdomains や、Cohesive Mechanisms を抽出 ( Distillation ) して分離する。
そうすると、分離して残ったものが、もう少し、濃厚な概念を持った状態になり、また、構造らしきもの、核の候補とかが見つけやすくなってくる。
楽観的なケースだと、Generic Subdomains と Cohesive Mechanisms を見つけて、分離しちゃうと、残ったものが、 Core Domain モデルの初期バージョン、ということだってありそう。
もちろん、
・Generic Subdomains の引き出しを多く持っていること
・コレクションフレームワーク、永続化フレームワークを適切に使っていること
が前提ですね。