if や for は、まとめて、カプセル化 : Cohesive Mechanisms パターン

ドメイン層で、if 文や、for 文がぐちゃっと、書かれた部分を見つけたら、たぶん、Cohesive Mechanizms パターンの出番。

ドメインモデルの中で、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 の引き出しを多く持っていること
・コレクションフレームワーク、永続化フレームワークを適切に使っていること

が前提ですね。

どう作ろうか? : Generic Subdomains パターン

ドメイン(問題領域)のモデリングを始めると、「よくでてくる、部分的な問題」がいろいろ見えてくる。
こういう所は、できるだけ、手間をかけずにサクッと解決したい。

エヴァンスは、Domain-Driven Design(DDD) で、Generic Subdomain の設計・実装のやり方を、4つ上げている。

A.オフ・ザ・シェルフ ( 買う、または、オープンソースソフトの利用)
B.公開されている設計や分析パターンを参考にする

C.実装を外注(コアの技術者以外にやらせる)
D.社内で部品ライブラリとして整備

作る場合(外注でも内製でも)、設計は、

■(オフザシェルフの)設計を参考にする
■公開された設計や分析パターンを参考にする

のどちらかになる。(よくある問題を、白紙から設計する、という選択肢はない)

どの手段を選んでも、メリット、デメリットがあって、選択は難しい。

いや、私たちの場合、Generic Subdomain の設計・実装は

「公開された設計・分析パターンを参考にして」
「自分で作る」

がほとんど。

なぜ、そうなるか?

オフ・ザ・シェルフ


エヴァンスがあげている、デメリットが、やっぱり問題だと思う。

購入するにしても、オープンソースにしても

・仕様やコードを詳細に調べて、評価するのが結構たいへん。
・ソフトウェアの安定性とか、バグ対応とかが、自分でコントロールできない
・汎用性を重視し、仕様が肥大化していることが多い
・設計の思想・発想が、自分たちのと違っていて、結合部分がぎくしゃくする
・特定のOS、ミドルウェア、開発ツールなどに依存していることがある

というのは、やはり、負担になる。

日付API


日時や期間は、典型的な Generic Subdomain。

オープンソースで Joda Time - Java date and time API は、わりと使われているらしい。

でも、この API の 内容に精通して、使いこなすには、それなりに時間が必要。
しかも、こんなにいろいろなことができる必要はない。

ワークフローエンジン


エヴァンスは、オフザシェルフの成功例として、「込み入った」ワークフローアプリを実現するために、商用のワークフローエンジンを API ベースで利用してうまくいったプロジェクトを知っていると書いている。

確かに複雑なワークフローを実現するには、こういう解決策もあるかもしれない。
でも、ちょっとしたワークフローなら、ワークフローエンジンの評価と導入より、簡単な状態管理のメカニズムを自前で実装したほうが、早いし、扱いやすいと思う。

この分野だと、Mule ESB で、 jBPM 利用とか、興味あるんだけど、まあ、ぼちぼち調査はしておこうと思っている程度。 (習得すれば、けっこう使えそうな気はしている)

ビジネスルールエンジンとかも興味はある。

(複雑な料金体系の)携帯電話の課金アプリケーションで実際に使っているのは知っている。
あのくらい、込み入った料金体系で、かつ、キャンペーンとかでも、変更が入る、という状況だと、商用のビジネスルールエンジン使うのも選択肢だとは思う。

参考にするけど、導入は?


私たちも、既存の業務アプリ製品や、オープンソースのドメインオブジェクトのコードは、調べて設計の参考にすることは多い。

でも実際に導入することはほとんどない。

エヴァンスも、オフ・ザ・シェルフのソフトウェアは「調査する価値はある。導入するのは、たいてい、割に合わない」と言っている。

インフラ層とかUI層は、オープンソースを徹底活用している。できるかぎり、自分たちでコードを書かないようにしている。

そのかわり、ドメイン層は、Generic Subdomain でも、基本は、自作。

設計は、公開されているソフトウェアの仕様やコードを参考にしています。

設計パターン、分析パターン


ファウラーの 「アナリシスパターン」とか Hruby の「ビジネスパターン」とか、ニコラの「ストリームラインオブジェクトモデリング」とかは、かなり参考にしている。

Generic Subdomain の分析・設計パターンとしては、どれも、とても参考になる。

ただし、パターンをそのまま実装したことはない。

できるだけ、自分たちのニーズに限定した簡略化したモデルにしてから、設計・実装している。

設計の参考にすることと、そのまま実装することとは、全くの別の話し。

目的は、Generic Subdomain の設計・実装をできるだけ、簡単に済ませたいだけ。
だから、パターンを忠実に実装しようなんて、考えたこともない。

公開された分析パターン、設計パターンは、一般モデルであって、具体的で、部分的な問題の解決手段としては、おもすぎる。

もっと、軽いモデルで設計・実装する。(考え方はとっても参考になる)

外注


予算がないこともあるけど、あまり外注も使わない。

設計意図を説明して、コーディング規約とかも理解してもらって、それなりのアウトプットを期待するには、かなり時間が必要。

時間もないし、そういうコミュニケーションのコストをかけるのは、いかにも効率が悪い。

しかも、コードの品質管理もばらつきがあってたいへん。

もっとも、レベルの高い技術者にお願いできる場合は、外注をしている。

同じメンバーで仕事をしていると、技術が偏ったり、あるレベルで停滞してしまう。

外部のレベルの高いエンジニアに良いコードを書いてもらうと、とても良い刺激になり勉強になる。
Generic Subdomains を簡単にすませよう、という意図からはずれるけど、こういう異なる文化との交流は、外注の大きなメリットだと思っている。

内製


結局これが、メイン。

ただし、一般化とか、再利用性とかの方向に走らないように、みんなで注意している。

Generic Subdomain は、手間ひまをかけずに、必要最小限のものを、最小コストで手に入れることが目的。

内製で危険なのは、いろいろやりはじめてしまった、ミニマムバージョン以上の作業をしてしまうこと。

コード量が増えれば、初期の開発だけでなく、メンテナンスのコストもばかにならない。

とにかく、 Generic Subdomain の設計・実装は、ミニマリズム (minimalism ) にこだわる。

別のプロジェクトなら類似のコードをもう一度書くことになっても、気にしない。

モデルや設計が再利用できれば、コードの実装そのものは、たいした作業じゃないから。
時間がかかるのは、モデリングや設計であって、コーディングではない。

もちろん、Generic Subdomain は、できるだけ、モデリング、設計・実装に時間をかけないこと。

そして、Core Domain にパワーをかける


Generic Subdomains は、できるだけ軽く片付け、できるだけ、コードをいじらないですませる。
そのかわり、Core Domain は、モデルのリファクタリングを繰り返し、設計・実装を継続的に改善する。

Core Domain は、プロジェクト初日に、ある程度、見定めて、最初の一週間で、設計・実装するようにしている。
あとは、少しずつ、Generic Subdomain の追加と、Core Domain の、ちょっとした改良を繰り返す。

最初にモデリングして、コード書くのは、かならず Core Domain にすること。
そこが、ソフトウェアの中核だから、そこに取り組むことで、プロジェクトの骨格が、早く決まってくる。

そのあと、Generic Subdomain を追加していく。
Generic Subdomain として、ある部分を、コードにすると、結果として、Core Domain の輪郭が明確になる。

Generic Subdomain の追加 が、必然的に、Core Domain の改良の引き金になる。

これ、どこが中核かなんて意識しないで、やっている開発だと、たんなる手戻り作業に見える。

でも、ドメイン層のコードを、 Core Domain + Generic Subdomains として扱うようになると、Core Domain の改良の繰り返し、積み重ねが、全体の作業量を、確実に削減してくれることが実感できた。

ソフトウェアの中核( Core Domain )が、わかりやすくなればなるほど、ソフトウエア全体が、びっくりするくらい、わかりやすく、扱いやすくなる。

急がばまわれというか、Core Domain に時間をかけると、つまらない手戻り作業が目に見えて減ってくる。

Core Domain に時間をかけると、全体の生産性があがる、というのは、体験しないと、ぴんとこないんだろうなあ。

これ、

・設計に時間をかけたほうが、早く、開発できる
・品質向上に時間をかけると、コストダウンを達成できる

などと同じで、わかっている人はわかっているけど、わかんない人には、わけのわからん考え方なんでしょうね。

よくある部分的な問題 : Generic Subdomain

Generic Subdomains パターンは、Generic の意味、Subdomain の意味を、どうとらえているかを、関係者で確認しあったほうが良い。

どうにでも、解釈できるし、自分の技術的なこだわりや視点によって、意味のとらえかたが、いろいろありそう。

Sub Domain


ようするに「部分的」問題ということ。

Core Domain も、いくつかの 部分( Sub Domain )に分解可能。

これは、インターネットの「ドメイン(名)」と「サブドメイン」もいっしょですね。
(英語圏の人たちは、同じ言葉として同じイメージで使っているはず)

ドメインが、全体で、サブドメインが部分。

単純な話しだけど、 Domain-Driven Design (DDD) の Generic Subdomains パターンの話しの前に、ここのイメージあわせは重要だと思う。

Generic


わたしは「よくある」という言葉で捉えている。

この言葉は、Java の Generic とかから、考えると間違う気がする。

むしろ、薬品業界の「ジェネリック医薬品」のイメージなんだと思う。

ジェネリック医薬品は「後発医薬品」で、先発医薬品の特許が切れた後とかに、さまざまなメーカーが、同種の医薬品を製造販売することを指す。

これ、呼び方も関係してくる。
後発医薬品が当たり前になると「消毒薬」という「ジェネリック」な名前が使われ、特定ブランド名では呼ばなくなってくる。

日本で、昔は、「コンピュータ」のことを「IBM」と呼ぶのが当たり前だった時代があるんです。
「情報システム部」ではなく「経理部IBM室」とか、あたりまえにあった。

(IBM から富士通に乗り換えても、IBM 室と呼んでいた会社があったらしい)

複写機も、昔は、「ゼロックス」。コピーすることを「ゼロックスしておいて」という言い方があった。

先発製品が独占的に強力なブランドを確立すると、そのブランド名が、「一般名称」的に使われる。

でも、後発製品がどんどん増えてくると、「コンピュータ」「コピー機」というジェネリックな名前があたりまえになってくる。

Generic Subdomains パターンの、Generic は、これと同じですね。

「よくある」「部分的」な問題、が、Generic Subdomain。
そして、その名前は「一般的な名前」にする。

パッケージ名と独立性(非依存性)


Generic Subdomainは、当然、ひとつの package として設計・実装する。
また、他のドメインオブジェクトに依存すべきではないから、Standalone (参照されるだけ)の package になる。

その時のパッケージ名に、「ドメイン固有」、「業界固有、業務固有」の名前をつけない、というのがGeneric Subdomains パターンの設計・実装の基本ルールでしょうね。

エヴァンスのあげた例だと、パッケージ名は、Timezone とか、InternationalDate とかになるんでしょうね。

たいせつなのは、このパッケージは「Generic」に保つこと。

もし、今のドメイン固有の概念とか、業界固有の概念が入り込みそうなら、

・ドメイン固有の概念
・ジェネリックな概念

という2層構造にして、分離しておく。

Generic Subdomains は、ドメイン固有の概念を簡単に記述できるようにする、汎用(どこにでもある)部品、という位置づけ。

日付や期間計算、単位つきの数量とか、通貨の換算とか、住所の表記、...。
いろいろありそうですね。

Generic Subdomains パターンの意図


このパターンは、「よくある」「部分的な問題」は、徹底的に手抜きをしよう、というのが意図ですね。

もちろん、必須の部品なので、ちゃんと用意する必要はある。
でも、「価値の源泉」「差別化のキー」ではないので、可能な限り、手間隙かけない。

どうやったら、「よくある」「部分的な問題」を簡単に解決できるかを考えるのが、Generic Subdomains パターンの意図なんですね。

Generic Subdomains アンチパターン


よくあるのが、せっせとリファクタリングして、より一般的に、より汎用的にして、再利用性を高めようとすること。

「よくある」問題なので、こういう発想もありがち。
でも、Generic Subdomains パターンは、時間とエネルギーを、可能な限り、Core Domain に振り向けるためのパターン。

だから、 Generic Subdomains のリファクタリングなんかやりはじめたら、完全な失敗パターンなんです。

もちろん「よくある」問題なので、「再利用可能部品」にしたい、というのは理解はできる。

モデルを再利用するほうが効率的


「再利用」は、コードレベルで実現するのはかなりたいへんです。
どんな環境でも、そのまま、ぴたっと使えるような設計・実装というのは、難しい問題。

「コード」ではなく「モデル」を再利用したほうが、効果的です。

「モデル駆動」じゃなくて「コード駆動」の発想しかないと、「再利用」=「コード再利用」になっちゃう。

「モデル駆動」だと「再利用」=「モデルの流用」。このほうが、はるかに効率的。

「再利用」という言葉から「コード再利用」をイメージするか「モデル再利用」をイメージするかで、「モデル駆動」派と、「コード駆動」派が、識別できる、ということかなあ。

「なんでも Generic」 アンチパターン


世の中には、業務アプリケーションを

・業務アプリなんて、みんな、いっしょ
・DBと画面項目とのマッピングフレームワークがあれば必要十分。

というイメージの技術者が結構、多いらしい。

いろいろな業務、業種に精通して、価値のあるソフトウェアを生み出しいて、それを、顧客から高く評価されている方がおっしゃるなら、理解はできる。(賛同はしませんが)

でも、納期までの作り捨て(?)プロジェクトみたいなことばかりやってきたらしい人に「業務アプリなんて、みんないっしょ」とか言われると、違和感がある。

「Core Domain 見えないから、同じにしか作れないじゃない?」
「ほんとに、それでお客さんの役に立っているの?」

という突っ込みも入れてみたくなる。

エヴァンスは、DDD の最初で、「ドメイン駆動設計」は、新しいものではなく、昔から、心ある(?)エンジニアが、役に立つソフトウエアの設計・実装で使ってきた、実績のある考え方・やり方なんだと書いている。

自分は、「Domain-Driven Design」という名前をつけて、実績のある考え方・やり方を、パターンとして表現しただけなんだと。

私も「ドメイン駆動設計」の考え方・やり方は、業務アプリ開発では、昔からある成功パターンを集めたもの、という印象が強い。

もちろん、アジャイルなやり方とか、フレームワークの活用という、時代の変化はあるけど、それはドメイン駆動設計の本質ではない。

Core Domain を見定め、そこの設計・実装を継続的に洗練させ、発展させていく。
それがドメイン駆動設計の中心課題。

ドメインがすべて「Generic Subdomain」に見えちゃうのは、ドメイン駆動設計では、究極のアンチパターンなんだと思う。

よくあるよね、こういうの : Generic Subdomains パターン

あるアプリケーションのドメイン(問題領域)は、コアと、それ以外の部分がある。

Core Domain には、もっとも優秀なメンバーを優先的にアサインする。

じゃあ、それ以外の部分をどうするか?

Generic Subdomains パターンが、その答えの一つ(すべてではない)。

タイムゾーンの例


Domain-Driven Design(DDD) で、Generic Subdomains の例としてエヴァンスが書いているのが、タイムゾーン付きの日時の扱い。

2つのプロジェクトを対比させて説明している。

国際輸送


「国際輸送」を扱うプロジェクトでは、貨物の「現在」位置や、到着予定を、出発地、到着地の「現地時間」で扱う必要がある。

しかも、輸送の途中で「日付変更線」を西から東に超えたり、東から西に超える。

ドメインモデリングの過程で、この「日時」の扱いが重要な課題として明確になった。

重要ではあるが、ここに独自のドメイン知識があるわけではない。
業務の知識として、常識レベルの知識であり、計算方法。

かといって、 Java API レベルで、扱うのは、かなりたいへん。
要求にぴったりあった、公開されたオープンソースとかも見つからない。

Core Domain ではないので、開発チームの中核メンバーはここにアサインすべきではない。

で、力はあるが、期間限定で参加している開発技術者に設計・実装をまかせる。

彼は、BSD Unix のライブラリなどを参考に、かつ、プロジェクトのニーズにフォーカスした、独自の日付ライブラリを開発。

Core Domain の設計・実装をサポートする、価値のある、Subdomain となった。

これは、Generic Subdomains の成功パターン。

保険請求の管理


北米をカバーする、保険会社で、保険の請求を管理するシステム。
北米の4つのタイムゾーンを扱う必要がある。

この程度の情報で、若手の優秀なエンジニアを割り当てて「複数のタイムゾーンを扱うための日付ライブラリ」という程度の単純な要求事項で、開発を始めさせた。(情報工学の大学院でもでてきたレベル?)

結果は、超・汎用的な、一般化された「りっぱな」な日付ライブラリの完成。

でも、モデリングが進んでみると、そんなライブラリはまったく不要だった。

事実として、「タイムゾーン名 + 時刻」という、文字列情報を記録すれば、必要十分。

日付の計算とかも、不要。

プロジェクト全体も、こんな調子で、開発リソースを無駄遣いして、結局、ぽしゃったらしい。

ドメインの理解が不足した状態で、「タイムゾーンを扱える日付ライブラリ」というような、どうとでも解釈できる仕様で、せっせと開発した結果がこれ。

「日付」という、どこにでも出てくる問題だけに、どんどん、汎用化、一般化していって、仕様がどんどん膨らんでいっちゃう。オーバーエンジニアリングですね。

完全なアンチパターン。

二つの対比


成功と失敗を分けたポイントは3つ。

・ドメインのモデリングをきちんとやって、ニーズを正しく理解する
・そこで明らかになったニーズだけにフォーカスする
・そのオブジェクトを使う側からの適切なフィードバック

失敗パターンは「一般的な要求事項」でいきなり作り始め、「ドメインのニーズ」とのつきあわせやフィードバックがない状態で、作り続けた。

いろいろな Generic(よくある) 部分的な問題


日付以外にも、通貨、会計処理(記録、転記など)、組織と部門、連絡先、...

いろいろな「よくある」、「部分的」な問題領域が見つかる。
こういうよくある部品は、必須だけど、そのアプリケーションの Core の価値を生む場所ではない。

だから、ありものをうまく使って、開発リソース配分も、きちんと考えて、コストパフォーマンスの良いやり方をやるべき。

エヴァンスは、やり方として

・外部から調達 (購入とかオープンソース)
・汎用のパターンや設計の流用
・作業のアウトソース
・自社ライブラリの開発

の4つのやり方をあげて、メリット/デメリットを書いている。

また、Generic Subdomains の取り組み方で、注意すべき点として、

・Generic(よくある)は、Reusable (再利用可能)でないよ
・技術者は、Generic Subdomains をとりあえず片づけたがるけど、それは、危険だよ

ということを書いている。

ここらへんの内容は、もうちょっと整理するために、次の記事で書こうと思う。

私自身は、業務アプリ開発で、それなりの経験をしてきたので、Generic Subdomains といわれると、なんとなくわかる気はする。

若手のメンバーを見ていると、業務アプリの経験(特に異なる業種や業務の経験)が少ないため、なにが、Generic ( よくある ) Subdomain なのか、ぴんとこないんだとう思う。

アナリシスパターンとか、ビジネスパターンとかで、パターン名なんかを知識として覚えてみても、実践で、どういう意味を持つパターンなのか、ぴんとこないみたい。(だから、結局、身に付かない)

Generic Subdomains パターンを、場数の踏み方が少ない若手開発者たちと、考え方、やり方を共通理解にしていくのは、ちと(かなり?)たいへんそう。

みんなにわかりやすく要点を伝える : Highlighted Core パターン

ソフトウェアの中心課題を、簡潔な文章で表現する Domain Vision Statement は、役に立つ。

でも、チームのメンバーの理解が共通かどうかは、ちと怪しい。
同じ文章を読んでいるのに、結構、違うことを考えているもんですよね。

そこで、Domain Vision Statement パターンよりも、もっと、具体的に、Core Domain を共通理解にするテクニック。

・3−7ページ程度のコアの解説ドキュメント (Distillation Document)
・既存モデルにマーカーで、色づけ ( Flagged Core )

Core Domain の解説ドキュメント (The Distillation Document)


数行の、Domain Vision Statement では、あいまいさが残るので、もうちょっと、具体的に解説しよう、ということ。

ボリューム的には、3ページから7ページ。(行間を空けて、読みやすくする)

内容は、

・主要なクラスに概要説明(言葉を慎重に選んだ文章)
・主要なクラス間の関係(クラス図、シーケンス図)

コードがイメージできるくらい、実装を意識した情報のほうが良い。

ただし、ソフトウェア技術者以外の、関係者が、読んで理解できることが絶対条件。

「実装まで想像できる」書き方と、「技術用語は使わない」ことは、ドメイン層の設計・実装では、矛盾しません。

クラス名、メソッド名は、業務を表現する名前(業務の言葉)のはずだから。

プロジェクトの初期には、裏紙やホワイトボードに手書きしていろいろやっていることを、ちゃんと記録して、読み返せるようにしておこう、という感じかな。

記録して読み返す、という意味では、写真とって、プロジェクトポータルにアップでも良いと思う。

でも「継続的に改良」するためには、編集可能な形式で書くほうが良い。

頻繁に変更するわけではないけど、Core Domain のモデルに変更があった場合は、ソフトウェア全体への影響が、大きい。

変更があったら、ドキュメントを更新して、かつ、それをチーム全体に、周知徹底する必要がある。

実践できているか?


Distillation Document レベルのものは、裏紙の落書き、ホワイトボード使って、手書きで要点説明、などでやってはきた。

「ここがポイント」とか「基本の構造」を共有すべきことは、意識してきた。

でも、共有可能で、更新可能なドキュメントにはなっていないのが実情。

なぜ、ドキュメントにしてこなかったか?

アイデア出しフェーズでは、思考のスピードに追いつくのは、手書きでもたいへんなくらい。ましてや、ドキュメントにするのは、あまり価値を感じていなかった。

DDD の Highlighted Core パターンを、読み直してみると、ちゃんとドキュメントに整理して、言葉を選びなおして、整合性をチェックすることは、大きな価値(効果)がありそうだと思いなおし始めたところ。

もうちょっと、ちゃんとドキュメントにして共有するように、トライアルしてみようと思う。

既存モデルにマーカーで色づけ (The Flagged Core)


これは、実践的、実用的。

既存のモデルがあるなら、その中で重要ポイントをマーカーで色づけしていく。

Core Domain を明らかにするには、これは、かなり有効ですね。

開発チームは、既存のモデル、その設計・実装に親しんでいるわけだから、どこか重要で、どこか重要でないかの、議論・理解が、とても具体的になる。

エヴァンスは、本の中で、自分の経験で「200ページ」のモデルから、要点をマークアップして Core Domain を具体的にしていった話を書いている。
(数日で、やっちゃたらしい)

これ、私は、人材ビジネスの汎用モデル ( Published Language ) HR-XML で、似たようなことはやった経験がある。

求人情報の表現モデル、履歴書・経歴書の汎用的な形式、選考プロセス、採用プロセスの一般モデル、...

山のようなドキュメントをかき分けながら、要点(自分たちに特に関心がある点)をマーキングしたことがある。

全体構造とか網羅性はしっかりしているので、その中から、要点をマーキングしていくのは、効率が良いやり方だと思う。

もっとも、自分で整理しただけで、関係者で共有したわけではないので、エヴァンスの言う、The Flagged Core パターンにはなっていない。

エヴァンスは、モデルが「コミュニケーションの道具」であることに、ほんとうにこだわっている。

一人の人間が、ドメインを深く理解することが重要なのではなく、チームとしての理解が重要なんだと。

ここらへんは、自分は、ほうとうにまだまだだと思う。
振り返れば、一人で分析・設計して、まわりにうまく伝えられない、という失敗ばかりしてきたような気がする。

正直言って、「わからないやつがレベルが低い」「わからないやつと話すのは時間のムダ」という感覚で仕事やってきた気がする。

Domain-Driven Design(DDD)に出会ってから、発想ががらっと変わった気はする。それでも、日常の実践になると、まだまだ「チームで共有」へのこだわりが足りないんだと思う。

日々精進はしているつもりですが...

ドメイン駆動設計の基本中の基本

Domain-Driven Design(DDD)を読み直している。

Domain Vision Statement パターン (415ページ)にたどり着いた。

これ、ドメイン駆動設計の基本中の基本のやり方だと思った。
現場で、まだ、実践できていないけど、これから、Domain Vision Statement パターンを徹底してやってみようと思う。

Core Domain の文章表現


Domain Vision Statement は、いま造っているソフトウェアの基本価値を、文章で表現したもの。

エヴァンスは、1ページ程度といっているけど、もっと短くてもいいと思う。
(最初は、長めで、だんだんシェイプアップしていく?)

大切な点:

◎業務の言葉で、業務の関心事を書くこと
◎今回のソフトウェアのこだわりポイントを書く
◎技術者以外のレビューとフィードバック
◎なんども、書き直す

業務の言葉で業務の関心事を書く


これ、技術者には、ハードル高い。
技術用語は一切禁止で、自分が取り組んでいるソフトウェアを説明できますか?

でも、だからこそ、書く価値があるし、書く効果もてきめんのはず。

もっとも、視点は、技術視点、設計・実装の視点でよいと思っている。

ドメインオブジェクトの基本設計をしていると考えればよい。

こんなドメインオブジェクトが必要だろう、と考えながら、日本語でオブジェクト名を考えていけばよい。

良い「仕事」を探して、「応募書類」書いて、応募する。

こんな感じで、まず、このソフトウェアの骨格を書く。

文が苦手だったら、クラス図で、キーワードをクラスにしてみてもよい。
コード大好きだったら、

class 仕事 , class 応募書類, class 応募 extend event, ...

てな感じでもよいかもしれない。

でも、最後は、必ず、文にしてみる。

文、図、コードは、それぞれ、見る角度、表現の強み・弱み、が違う。
同じテーマを3つの手段で表現してみると、いろいろ発見がある。

得意なやり方だけやって、苦手なやり方を避けていると、見方が歪み、見落としや失敗が増える。

文、図、コードは、バランスよく使うのが良い習慣。

ソフトウェアのモデリング、設計・実装というのは、いつも

・文(言葉)表現
・図(スケッチ)表現
・コード 表現

を行ったり来たりするもの。

Core Domain をコードにするには、絵を描いたり、文にしてみるのを併用すべし、というのが、 Domain Vision Statement というわけだ。

こだわりポイントを書く


一般的なソフトウェアの機能を書いても、役に立たない。
書くのもつまらない。

今までのソフト、類似のソフトとは、ここが違うぞ、という「こだわりポイント」をなんとか言葉にしたい。

この「こだわりポイント探し」が、 Domain Vision Statement パターンの核心でしょう。

仕事を探すなんていうサイトは、たくさんある。
自分たちも、いままでも、何種類かのサービスを提供している。

今度のプロジェクトは、それと、どこが違うんだ?
なぜ、既存のソフトウェアではなく、別途開発プロジェクトが立ち上がったんだ?

このプロジェクトに独特の「こだわりポイント」がうまく言葉にして、チーム内で共有すれば、すべての活動の連携やバランスがとれるようになる。

ソフトウェアの開発で、平坦な機能リスト、タスクリストを書きだして、割り振って、淡々とこなしていくのは、(ドメイン駆動設計的には)アンチパターン。

めりはりをつけて、今回のソフトウェアのこだわりポイントを中心に、すべてを組み立てて調整していくのが、良いやり方。

今回のキーワードは何かな?
まあ、進行中のプロジェクトなんで、あまりネット上に生々しく書くわけにはいかないけど、検索機能に不満があることは事実。ここを、今までとは別の視点から改善する、というのが重要なこだわりポイント。

あとは、キーワードは「連携」だな。ここをブレークスルーするのが、たぶん、一番のポイント。

こだわりポイント以外の以外の一般的な話は、どんどん削る。
そうすることで、こだわりポイントを単純にわかりやすくする。

Domain Vision Statement も、コミュニケーションの道具だから、シンプルで、誰でも理解しやすことは、とっても重要。

継続的に書きなおす


プロジェクトの開始の時は、ドメインのことはよくわかっていない。
今回だって、こだわりポイントは見えているけど、つっこんだ分析や検討はこれから。

やっていくうちに、わかってくること、明らかになってくることがたくさんでてくる。

そのうちのいくつかは、当初の「こだわりポイント」文を書きなおすネタのはず。

Domain Vision Statement は、人員の配置、エネルギーのかけかたの軸になるから、軸の違っていては、開発がとんでもない方向によれていく。

Domain Vision Statement の見直しと、改善は、必須。

ドメイン駆動設計の基本


Domain Vision Statement は、ドメイン駆動設計のエッセンス。

ユビキタス言語


Domain Vision Statement は、「ユビキタス言語」の出発点であり、集約点になる。

Domain Vision Statement は、業務の専門家、経営層にも、読んてもらい、フィードバックを受ける。

× 技術用語がまぎれこんでいる
× 関心事がずれている
× ロジックが、ビジネスのロジックではない

こういうフィードバックがいろいろでてくるはず。
ここで、用語、考え方、重要な関心事をすり合わせることができれば、ソフトウェア開発のリスクは、ずいぶん軽減する。

「ユビキタス言語」の出発点、最初のトライアルとして、 Domain Vision Statement の初版を書くべきなんだ。

モデル駆動設計(MDD)


モデルの表現は、UML の図とは限らない。

もっとも簡単で、ある意味、もっとも論理的なのが「文章」です。

文は、絵と違い、リニアに、一方向にロジックを組み立てていく必要がある。

だから、たいへんなんだけど、それだけの価値もある表現方法。

モデル駆動の第一歩は、「文を書こう」ですね。

どうやってやろうか?


今までやって来なかったことをやろうとするわけだから、やり方をちょっと、考えたほうが良いかな。

まあ、いつもの調子で、

◎シンプルにやることを宣言
◎とりあえず試作をやらせてみる
◎やりながら、修正

でもいいか。

定期的に見直そうとか、バージョン管理しようとかいいだすと、小学生ルールになっちゃいそうだからなあ。

あ、でも、ほんとうは、 trac の wiki トップで、やろうとしていたんだ。

でも、プロジェクトの初期にちょこっと、 Domain Vision Statement らしきものを書いて、そのまま、という失敗パターンだった。

どうする?

書く場所は、適切。問題は、利用もされず、改善もされないこと。
もう一度、復活させてみるか?

私が定期的に見て、かならず、コメントしたり、修正をアドバイスを地道に繰り返せば、そのうち習慣になるだろう。

今までも、設計の考え方とかは、一度や二度では伝わらなくて、時間をかけて何度も何度も、言い続けてきた。

コードのテクニックとか、APIの使い方で、その場で、「おお」というネタだとすぐ覚えてくれるけど、「考え方」とか「継続して初めて効果が出る」というネタは、難しいんだよねえ。

でも、粘り強く同じことを言い続けると、いつもまにか、それがチームの習慣になっていた、という成功体験を何度かしてきた。

Domain Vision Statement も、trac wiki に書き、改善し続ける。

これを習慣づくまで、同じことを言いづけてみよう。

Domain Vison Statement は、ドメイン駆動設計の基本中の基本。
ここがチームの習慣になったら、結構、すごいかも。

Core Domain の抽出パターン

Domain-Driven Design (DDD) 15章に出てくる、Core Domain の抽出テクニックは、6つ。

・Domain Vision Statetment
・Highlighted Core
・Generic Subdomains
・Cohesive Mechanisms
・Segregated Core
・Abstract Core

どういう順番でやることも可能。
でも、設計・実装へのインパクトには、だいぶ違いがある。

Domain Vision Statement


「重要な関心事」を短くまとめた文章。

・簡単に、作成、修正できる。
・チーム内で、基本イメージやキーワードを共有できる。
・設計・実装には、影響はない。

Highlighted Core


既存のモデル(クラス図やパッケージ図)で、重要な所を、赤でマーキング、というようなイメージ。重要なクラスと関連だけを抜き出した概要図でも良い。

・簡単に、作成、修正できる。
・リファクタリングのポイントや方向性を議論し、判断しやすくなる
・設計・実装には、直接、影響はない。

Generic Subdomains


「一般的」な、モデル、設計、実装で済ませる部分を「抜き出す」。

・全体を整理できる。 ( Core が明確になる )
・既存のパッケージやコードの設計変更を伴う

「Generic Subdomain の抽出」というリファクタリングですね。

Cohesive Mechanisms


「アルゴリズム」とか「手順」を、抜き出し、カプセル化(と隠蔽)。

・コードの見通しがよくなる( Core が明確になる )
・既存のパッケージやコードの設計変更を伴う。

「Cohesive Mechanisms の抽出」というリファクタリングですね。

Segregated Core


Core Domain を、明示的に、ひとつのパッケージにまとめる。

Generic Subdomain や Cohesive Mechanism は、「ある部分の特定の役割」を発見して、抽出する作業なので、比較的やりやすい。

Core を抜き出して、ひとつのパッケージにすることが、簡単にできれば苦労はしない。
Hilighted Core とかのモデルから出発する作業になるけど、既存の設計・実装への影響はかなり大きい。

複数のパッケージに影響が及ぶ可能性が大きい。大仕事ということ。

Abstract Core


これは、超難問。

Generic Subdomains, Cohesive Mechanisms, Segregated Core の三つは、既存のクラスを、分類整理するイメージ。 同じレイヤでの分割作業。

Abstract Core は、既存のドメインオブジェクト群の中から、隠された「Core の概念」と「基本構造」を抽出するパターン。

隠された Core 概念や基本構造を発見するだけでも、難題。

これを、Abstract Core パッケージに抽出して実装すると、多くのパッケージ、クラスに大規模な修正をすることになりそう。

いきなり、やるような作業じゃないことは確か。

これ以外の「 Core Domain の抽出」テクニックを地道に繰り返した結果として、この Abstract Core にたどり着く、というシナリオはあるかなあ?

考え方は、勉強したほうが、よさそうだけど、現場で使えるテクニックでは、なさそうな気がする。

Core Domain を誰が開発する?

開発プロジェクトの初期には、技術者は、その問題領域(ドメイン)の知識が少なく、理解も浅い。たぶん、あまり興味もない。

Core Domain が問題の核心で、Core Domain のモデリングと設計・実装が、ソフトウェアの価値、プロジェクトの成果を大きく左右する。

Core Domain の開発は誰が、どうやるべきか。

・パターン(ベストプラクティス)は?
・アンチパターンは?

ベストプラクティス


もっとも優秀でやる気のあるメンバーを集めて、そのチームに、Core Domain のモデリング、設計・実装をやる。

ソフトウェアの価値、プロジェクトの成果を左右する核心部分だから、当然ですよね。

現実には、技術的には優秀だし、経験も豊富だけど、ドメインを理解したり、ソフトウェアで表現することに、興味を持たない技術者が大勢いること。

私の場合は、私が部門の責任者なので、

・ドメイン層の設計・実装が、最大の成果
・ドメイン層を作るのが優秀な技術者

という価値観を徹底(強制?)しているので、比較的、話しは簡単。

RDRA(リレーションシップ駆動要件定義)と、ICONIX(ユースケース駆動開発実践ガイド)のやり方で、ドメインをモデリングさせる。

ドメインのモデルのレビュー・改良に一番時間をかける。

その中で、いちばんモデリングの意欲とスキルの高いメンバーを、 Core Domain に割り当てる。

技術者の評価基準は、「インフラ層のコードを理解したり自力で書ける」ことは軽視。
「ドメインを理解し、モデルに描ける」ことを重視して、評価、指導している。

どちらかというと、技術的にとんがったメンバーが少ないチームなので、わりと、素直に「ドメインのモデル」重視、というカルチャーになってきた。

腕自慢のメンバーと仕事をする時には、私が責任者である限り「ドメインの理解」「ドメインへの興味」が、第一優先事項ということを、明言し、徹底している。

もちろん、力のある技術者からは、反発や、技術力の評価が不当に低い、という不満はたくさんでてきます。

一般論とか、個人の価値観とかまで立ち入る気はない。それは、個人の自由。

ただ、私は、ソフトウェア開発プロジェクトの成功の鍵は「ドメイン駆動設計」であり、Core Domain の設計・実装であることに、信念を持っている。私が責任者である限り、この価値観は徹底することにしている。

技術者たちが、業務の言葉を積極的に理解し、それをソフトウェアで実現しようとしている、という雰囲気が、まわりに伝われば、プロジェクトがうまく回りだすことを、何度も経験している。

もちろん、良いソフトウェアを作るには、インフラ層も、UI層も、良いソフトウェアにする必要がある。ただし、それは必要条件で、十分条件からは、ほど遠い。

ドメイン層の充実・洗練、中でも、 Core Domain の充実と洗練が、価値のあるソフトウェアの十分条件。

だから、Core Domain には、もっともやる気があって優秀なメンバーを割り当てる。

アンチパターン


Core Domain に優秀なメンバーを割り当てないのは、アンチパターン。失敗パターンですね。

アンチパターンとしては、

・初心者任せ
・外部コンサルタントの支援
・既存ソフトの外部調達

がある。

初心者まかせ


腕自慢の技術者は、彼らが興味を持つ、インフラ層や、UI コントロール、自作のフレームワークやライブラリの開発、などのテクニカルなタスクに割り当てる。

実際の業務の機能は、初心者クラスのメンバーに、「この通りやれば動くから」といって、丸投げ。

データベースの項目と、画面の項目をせっせとマッピングするだけの仕事なんて、ほんとの技術者のやる仕事じゃない...

こういうプロジェクトが世間では多いのかなあ?

良い悪いという議論をする気はないけど、「ドメイン駆動設計」的でないことは確かですね。

「ドメイン層」こそ、ソフトウェアの価値の源泉だと思うんだけどなあ。

外部コンサルタントの支援


プロジェクトの初期に、アナリスト、モデリングのプロ(?)、その業務に強いベテランSEとかを、かりだすパターン。

そのプロジェクトにべったりというわけにいかないので、プロジェクトの初期に短期だけ。

彼らに Core Domain をやらせれば、それなりに、良い仕事をしてくれる。
プロジェクトに専任予定のメンバーたちより、「上流」で力の差があることが、はっきりしている。

でも、問題は、彼らが抜けた後。

ドメインモデルは、継続的に、地道に改良・発展させていくもの。
ましてや、Core Domain こそ、いちばん、エネルギーと時間をかけて、継続的に発展させていく。

短期の高級(高給)メンバーが、やった仕事は、出発点としてレベルが高いかもしれないけど、それを、設計・実装し、育てていくのは、元々のプロジェクトメンバー。

彼らは、それらしいドメインモデルがあっても、実コードではないので、理解ができず、白紙から、コードレベルで、格闘することになる。

高い金を払って、モデルを作っても、誰もそれをありがたいとは思っていない。

これも、典型的な失敗パターンですね。

もし、コアのプロジェクトメンバーが、ドメイン層に真剣に取り組みたいと思っていて、彼らを、Jump Start させるために、ブースター役として、外部の優秀なスタッフに手伝ってもらう、というのはありだと思う。

でも、主役は、あくまでも、プロジェクトのメンバーじゃないといけない。

既存ソフトを外部調達


Core Domain の外部調達はありえない。

すくなくとも、開発プロジェクトで、「ここが核心」という部分は、自分たちで開発すべき場所。
そうじゃなかったら、そもそも、その開発プロジェクトは実施されていないはず。

■ 他の目的や背景に基づいて作られたソフトウェア
■ どういう環境でも、汎用的に使えるように、一般化を重視し、カストマイズ機能をヘビーに作りこんであるソフトウェア

こういうソフトウェアは、今のプロジェクトの問題の核心 ( Core Domain ) を解決するソリューションとしては、ぴったりくるはずがない。

なんでも自作、という主張をするつもりはありません。

でも、「Core Domain」だけは、自作し、継続的に育てる以外に、良いやり方はない。

Core Domain 開発 ベスト・プラクティス


Core Domain のモデリング、設計・実装に、優秀なメンバーを投入することが、役に立つソフトウェアを造り出す、ベストプラクティスなんです。

優秀なメンバーを、Core Domain に、できるだけ長期間、割当て、継続的な洗練を地道に続け、Core Domain の設計・実装を発展させていく。

他にいろいろしわ寄せが来るけど、そっちは、別の手段で、なんとか、やりくりする。

プロジェクトの人員配置、時間配分、外部資源の調達は、すべて、Core Domain を中心に、判断をしていく。

Core Domain の選択

システム構想図を分解して、10の Bounded Context を洗い出した。

ちょっとかわった商品の

・売買のマッチング
・注文の実行
・支払い決済

というシステム。

データ管理系の Contextの洗い出し


10のBounded Context のうち7つは、よくある、データベースの CRUD アプリケーションだな。

データの登録と、findByID() と、search( 抽出条件 ) が、できれば、十分。

問題は、データ項目と検索条件の設計が、 Core の関心事か、どうか。

視点にもよるけど、とりあえずは、

・既存のデータ項目
・一般的な検索条件

でも、そこそこ役に立つものはできそう。

Generic Subdomain というやつだな。
一般的なモデルと設計・実装でも、なんとかなるでしょう。

そうすると、Core Domain の選択は、十択問題から、三択問題に、問題が小さくできた。

残ったドメイン


残った三つは、

A. 売り手の条件と買い手の条件とのマッチング
B. 将来の在庫の管理 ( 入庫予定と出庫予定 から導出 )
C. 出荷内容、出荷時期、出荷経路の最適化 (動的な調整)

という感じ。

どれも、今は、ベテランの経験、ノウハウを元に、ほとんど人間が対応している。

どこも、Core Domain というか、新サービスの競争力の源泉、差別化ポイントになりそうだなあ。

あとは、視点の設定かなあ。

誰の利益を重視する?


マッチングサービスなんで、主要な登場人物は、

・売り手
・買い手
・サービス提供者

になる。

売り手と買い手が対等?

ここが、ポイントになりそうだなあ。

非対称にできないか?

うーん、難しいか。でも、まてよ、そもそも、一つのサービスじゃなく、2つのサービスにわけちゃったら、どうだ?

これ、Win - Lose の関係じゃ、ないんで、

A.売り手側の利益を優先したモデル
B.買い手側の利益を優先したモデル

と単純化して考えて、2つのモデルを作って、それを付き合わせると何かでてきそうだ。

買い手重視のモデル


投資効果を最大にするためのロジックが、コアドメインだな。
同じ資金を使って、効果を最大化するために、刻々と、投資効果を測定しながら、投資配分を変えていく、というところが Core Domain。

売り手重視のモデル


自分の商品の稼ぎを最大化するロジックがコアドメインだな。
売れ筋は、価格を上げたいし、不良在庫は、叩き売り、みたいな判断と行動を支援できればいいんだ。

うん、ちょっと、手がかりが見えてきたぞ。

Core Domain パターン : 原点を決めれば、わかりやすい

むちゃくちゃな一週間だったなあ。

けっこう大規模な新システム構想が持ち上がったので、

・クライアントと打ち合わせ
・提案活動
・メンバーの緊急招集
・たたき台づくり
...

で忙殺された一週間。

ほかの仕事がなくなったわけではないので、もろ追加の仕事。

まあ、ここに書く時間は、削ったわけだが、ちょっといやな感じがしている。

確かに、Domain-Driven Design(DDD)をじっくり読み返して、考えをまとめなおして、文にしてみる、という時間は、とれなかった。

でも、タスクに追われているだけでは、どうも、道を誤りそうな、恐怖感を感じはじめた。

構想が大きいだけに、無理やり、「じっくり考える」時間をとるべきなんじゃないかと。

ここに書くことができていれば「考える時間をとっている」という、チェックポイントにしようかと思いなおしたところ。

まあ、それを、休日にやっているは、問題なんだけど。

全体の見通しの悪さ


ソフトウェア開発は、ちょっと規模が膨らんでくると、全体が急速にわかりにくなってくる。

結局、Smart UI というか、縦割りに役割分担して、メンバー間、プログラム間の依存性を極端に減らして、それぞれ狭いところだけ掘ってもらうことになりがち。

さすがに今回の案件は、このやり方ではうまくいかなそう。

構想自体、新事業全体をカバーする ERP みたいなところがあって、販売管理、在庫管理、出荷、債権・債務管理、...みたいに、スコープが横にだーっと広がっている。

新事業なので、ビジネスモデル自体もあやふや、流動的。
この状況にフィットする、パッケージなんか世の中にあるわけもない。

今日、いろいろ整理して、10くらいの Bounded Context でやろうか、という感じになってきた。

どれも、必要な機能ばかりだし、どこも、結構、根の深い複雑な問題が潜んでいそう。

順番にひとつずつ、という個別撃破戦略は選択できない状況。

かといって、じっくり、全体を調べて、緻密な開発計画の立案作業、という選択肢もない。

来週には、みんなで走り出すしかないし、2か月くらいで、なにか、元ネタになるソフトウエアを動かさなきゃいけない。

全体が広く、複雑で、見通しが悪い。
やみくもに突っ込んでいっては、玉砕が目に見えている。

原点を仮決めする


こんな、状況でも、それでも DDD じっくり取り組むぞ、と思いなおし、Core Domain パターンを読み直し始めたら、ひらめいた。

Core Domain (問題の核心)って、じっくり検討して見つけ出すもんじゃないんだ。

むしろ逆。

「Core」を仮決めしちゃって、それを原点(真ん中)においてみて、ほかの要素の位置関係や距離を、配置しなおしてみればいいんだ。

システム構想図みたいなものはあるけど、これは、データフロー系の絵で、情報のおもな流れと、データストア(DB)の概念図。

ビジネス全体の流れでは、全部重要で、必須の要素なので、どこがコアとは言えない。

でも、そこをあえて、コアを決め、他の要素は、コアに対して、どういう役割かを決めていけば、全体の見通しがかなりよくなりそう。

・誰にどこを担当してもらうか
・最初に手をつける場所
・限られたメンバーと時間の中で、深堀する場所、軽く済ませる場所
...

こういうのは「これが Core」と決めれば、話がずいぶん単純になる。

・Core に、優秀なメンバーから投入。
・Core への貢献度の順に、人員や投入時間の配分比率を変える。

プロジェクトの進め方の骨格ができちゃいそう。

どれを Coreにする?


Core Domain パターンの後半に、やり方がいくつか書いてありそうだけど、とりあえず、お手軽な方法で、着手したところ。

Bounded Context (重要な関心事)が、10個というのは、だいたい見えている。

内容の詳細に不明な部分は、多いけど、それぞれの「関心事」のキーワードは、ある程度、理解できはじめた。

だったら、これ10択問題ですね。

候補は、10個。そこから、"Core Domain" を「ひとつ」選べばいんじゃないか。簡単(?)。

10個を、順番に、「これが Core だとしたら」と仮置きしていったら、10種類の別のビジネスシナリオができあがる。

「ここが、Core 、ここが一番の収益源となる、そういうビジネスのイメージ」を考えると、どれを Core にするかで、イメージ、ビジネスのシナリオがはっきり違ってきた。

正直、私ひとりでは決めれないし、決めるべきでもない。

でも、ここを Core に考えると、こんなビジネスシナリオになりそうですねえ、という「候補のシナリオ」をいくつか提示できそう。

関係者に集まってもらって、いちばんしっくりくるビジネスシナリオを共有できれば、それが、Core 。

やっていくうちに、ぶれていく可能性は大きいと思うけど、

A. 決まるまで待つ。じっくり調査して検討。
B. ある程度わかったら、まず、やってみる。その結果で判断しながら調整していく。

の二者択一なら、話は、簡単。 B しかないです。

今回のクライアントは、私の持ち味、仕事のスタイルを良く知っている人なので、A が望ましいなら、私ではなく、別の人を呼んでいるはずだから。

とりあえず決めちゃう


Core Domain パターンを最初に読んだ時は、ほんとうに重要なところだから、時間をかけて、じっくり見つけ出さないといけない、と思い込んでいた。
(ほんとうは、そうなのかもしれない)

でも、今の状況で、読み直してみたら、

・とにかく仮置きしちゃう
・Core を仮置きできれば、全体の見通しが、ぱっと良くなる
・全体が見通せれば、議論がかみあってくる
・結果として、正しい Core に早くたどりつける(はず)

というようなイメージが、ぱっと頭の中にひらめいちゃった。

Core Domain って、もしかしたら、あるのか、どうかもわからないし、そもそも、 Core を「正しく決める」なんて、できないのかもしれない。

でも、実践的な手段として、

・ここが原点と宣言して、それぞれの関係を位置づけちゃう
・異論がでてきたら、大成功
・議論の結果によって、原点におく Bounded Context とか、位置関係とかを変えながら、よりしっくりくるモデルを探し続ける。

Core Domain パターンは、論理的な解としてCore Domain を導きだすためのパターンではない(?)。

単なる整理の道具、全体の見通しを良くして、コミュニケーションをかみ合わせるための手段、として割り切って使う現場のテクニック。

この解釈がぴったりくるんだよなあ。今の私には。
実際に役に立ちそうだし。

エヴァンスの意図とは違うのかもしれないけど...

calendar
 123456
78910111213
14151617181920
21222324252627
28      
<< February 2010 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM