たなかこういちの開発ノート

システム開発に携わる筆者が、あれこれアウトプットするブログ

ドメインとデータ、サブジェクトとオブジェクト、および、事実は常に事実であり、真実は常に仮説である、という話

先日参加の「PHPメンターズセミナー」には相当に触発されました。本記事はその勢いのままに書いたエントリーとなります。
 
※下記記事もご参照ください。
 
 
〜・〜
 
突然ですが、下図は、視点Aから見ると対象物は四角に見えて、視点Bから見ると三角に、視点Cから見ると円に見えるという様子を表したものです。一つの同一の対象物なのに視点によって見え方が異なる、という現象を説明するのによく使われるようです。
 

f:id:tanakakoichi9230:20151101212817j:image

図1:四角、三角、円の三面図
 
例えば、渡辺幸三氏が下記記事にて、ご自身の「三要素分析法」を説明するのに用いています。『一つの開発対象システムだが、「データモデル」、「機能モデル」、「業務モデル」の三つの異なる視点、観点がある。各観点での設計をそれぞれ行って擦り合わせることで、対象システムの実体が浮かび上がる。』、、、このような趣旨の説明をされています。
 
ITmediaエンタープライズより、「データ、UI、業務手順の「3要素」をとらえる」:
 
次は同図に「Fact」および「Truth」という文言を書き入れたものです。即ち、、、『A、B、Cという各事実が認識されるだろう。しかし各事実それぞれは必ずしも真実そのものを表している訳ではない。真実とは複数の事実から浮かび上がるもの、または、個別の事実とは真実の一断面を表すもの。』、、、という訳です。
 

f:id:tanakakoichi9230:20151101212829j:image

図2:「Fact」と「Truth」
 
※この図もどなたかのツイートで見かけたものなのですが、出展は分からなくなってしまいました。。
 
この四角、三角、円の“三面図”に「Fact」と「Truth」を当てはめた認識のモデルは、非常に良く出来ていて、気に入っています。
 
〜・〜
 
ところで、渡辺幸三氏は、自身のブログで「データモデルをドメインモデル=アプリケーションに先行してデザインすべき」という主張をされています。
 
「設計者の発言」より、「データモデルはドメインモデルに先行する」:
 
◆注意◆
こちらの渡辺氏の記事において、渡辺氏は明らかに「ドメインモデル」という用語と「アプリケーション」という用語を区別せずほぼ同義として用いています。渡辺氏の云う「ドメインモデル」または「アプリケーション」を、私はここではいちいち「ドメインモデル=アプリケーション」と表現します。それは、後に言及するDDDの云う「ドメイン」と区別するためです。
 
『確固たるデータモデルが在ってのみ、および、そのデータモデルから導かれたモノとしてドメインモデル=アプリケーションがデザインされる場合に限り、各要件に対応した複数のドメインモデル=アプリケーションの相互運用が担保できる。各要件に応じたドメインモデル=アプリケーションを最初にデザインしてそれらを単に羅列しても、そこからデータモデルを見出すことはできない。』、、、という主張だと理解しています。
 
この主張を、先の“三面図”におけるFact、Truthのモデルで説明してみます。
 
◆注意◆
冒頭の方で紹介したITmediaエンタープライズの記事中にて、渡辺氏は三要素分析法の説明に同図を用いてます。しかし、渡辺氏自身は、データモデルとドメインモデル=アプリケーションの関係性を説明するのに同図を用いている訳ではありません。混同せぬよう。
 

f:id:tanakakoichi9230:20151101212842j:image

図3:「Fact」=「ドメインモデル=アプリケーション」、「Truth」=「データモデル」
 
即ち、『確固たるTruth(データモデル)が在ってのみ、具体要件に対応した個別のFact(ドメインモデル=アプリケーション)が一貫性を維持しつつ表現できる。Factをいくら並べてもただそれだけではTruthは見出せない。』・・・となります。
 
いかがでしょうか?渡辺氏の「データモデルはドメインモデル=アプリケーションに先行せねばならない。」という主張がよりよく理解できるのではないでしょうか。
 
〜・〜
 
さて、渡辺氏のこのような「ドメインモデル=アプリケーション偏重批判?」に対して、DDDはどのように答えているでしょうか。
 
DDDには、この点について、幾ばくかの曖昧さが内在していると私は思っています。
 
DDDがアプリケーション層とドメイン層を分けて扱おうとしている点をナイーブに理解する立ち場からは、エンティティを含むドメイン層こそが、渡辺氏の云うデータモデル同様の役目をまさに果たしている、と見えます。ドメイン層は、確かにOOで抽象してはいても、それはDDDがまさに云っている通り、基盤層の実装実情をラップしencapsulateするためであって、渡辺氏が批判?するような、特定のアプリケーション要件に特化した構造や振る舞いを持とうというものではない、というものです。渡辺氏の批判?ポイントはDDDもよく理解していて、まさにそのために、アプリケーション層とドメイン層を分け、渡辺氏がデータモデルを先行すべきと云っていることと全く同一の意味でドメイン層を先行させようと云っている、という理解です。しかし、この理解のドメイン層に振る舞いを持たせていくと、データモデルの機能独立性が失われるとして、渡辺氏の批判対象となるでしょう。一方、振る舞いを乗せないでいると、DDD側から「ドメイン層が貧血を起こしている」として批判されるでしょう。塩梅が肝要、ということになります。
 
一方、境界付けられたコンテキスト=サブドメインを捉えることに注視する観点からは、同一のデータ実体であっても、要求・要件の観点から似て非なるデータ構造が見出されるなら、異なる境界付けられたコンテキスト=異なるサブドメインとして捉えるべき、となります。(※この理解については、私のこちらの記事にも書きました。)この場合のサブドメインは同一データ実体に対して、複数存在し得ます。この場合のサブドメインは、渡辺氏がアプリケーションとドメインモデルを一体的なものとして捉えつつ批判対象としているところの“ドメイン”に近いでしょう。ドメインについてある種の分かりやすさはありますが、対して、基盤層側からドメイン層へどのようにマップするのか、不明瞭になってしまった気もします。
 
このような曖昧さを捉えるために、私は、前者の理解のドメインを「(ドメイン・)オブジェクト」、後者の理解のドメインを「サブジェクト」と名付けて扱うこととしています。
 
〜・〜
 
これまでの考察を総合すると、基盤層のRDBに格納されるデータ実体が、アプリケーション層に届くまでに、データ構造は本質的に二段階の変換を経るのだ、として整理できそうです。
 

f:id:tanakakoichi9230:20151101212910p:image

図4.永続化装置からアプリケーションまでのデータの流れ
 
第一段階目は、基盤層に属するRDBのシンタックスから、ドメイン層(およびアプリケーション層)を実装するための特定のプログラミング言語のシンタックスの世界へ1対1対応でマップする変換です。(※図中濃黄色の左向き矢印で表しています。)ここで「シンタックス」と云っているのは、この第一段階目では、RDB/SQLという実装方式の世界と、例えばJavaという実装方式の世界との相互変換を行うことが目的で、データの型や構造を表記する“シンタックス”は変われど(※例えば「VARCHAR」が「 java.lang.String」にマップされます。)、データ構造の“セマンティクス”については本質的には同一性を維持したままの変換を行うからです。ここでマップされたモノを、私の用語で「(ドメイン・)オブジェクト」と言っています。この「(ドメイン・)オブジェクト」は、OO言語にマップされてはいても、渡辺氏の云う「データモデル」に相当していると言えます。「(ドメイン・)オブジェクト」は、DDD(ナイーブ解釈)のドメイン≒“古典的エンティティ”に相当します。
 
第二段階目は、要求・要件横断的なデータモデルたる「(ドメイン・)オブジェクト」を、特定の要求・要件に対応した、私の用語での「サブジェクト」へマップする変換です。(※図中ピンク色の左向き矢印で表しています。)「サブジェクト」は境界付けられたコンテキストに一致します。(※一致するモノだと、私は定義しています。)アプリケーション層が参照するのはこの「サブジェクト」です。アプリケーション層が参照するモノという観点から、「サブジェクト」はドメイン層に属するといえます。この第二段階目の変換では、データ構造そのものの変換=セマンティクス・レベルの変換が生じます。というよりも、特定の要求・要件に適合するようなデータの“ビュー”を得ることこそが、第二段階の変換の目的です。そして、PHPメンターズセミナーで中西先生が語られていた「フォーム分析の理論」とは、まさにこの第二段階目の変換についての形式化であると云えます。(※これは勇気付けられる事です。)
 
図4では、その他次のようなことも表現しています。
 
  • 渡辺氏のモデル「三要素分析法」は、「抽象的なデータ構造」を表現するものとしての“ドメイン”というものを取り入れていないので、ここでいう二段階のデータ変換といったものの存在について明確な言及はありません。(※渡辺氏のモデルでは、「抽象的なデータ構造」やそれを生成するデータ変換は、“ドメイン”ではなく「機能モデル」として扱います。)
  • ナイーブ解釈のDDDでは、私の用語でのサブジェクトの存在が不明瞭で、第二段階目の変換が、ドメイン層とアプリケーション層に散っています。これは、DDDの要請と渡辺氏の指摘とを両立するには『塩梅が肝要』な様子を表しています。
  • 境界付けられたコンテキスト=サブドメインを捉えることを注視するDDDでは、サブドメインは、まさに私の用語でのサブジェクトを意識した構成となります。その一方で、基盤層のデータ構造をどのようにドメイン層に取り込むのか、不明瞭になっています。 
 
〜・〜
 
ここで冒頭のFactとTruthによる認識モデルを以って、改めてサブジェクトと(ドメイン・)オブジェクトを説明してみます。
 

f:id:tanakakoichi9230:20151101212854j:image

図5.サブジェクト=Fact、(ドメイン・)オブジェクト=Truth
 
つまり、私の用語でのサブジェクトが個々の「Fact」であり、(ドメイン・)オブジェクトが「Truth」だという理解です。個別的な要求・要件を表現するサブジェクトはまさに個々の「Fact」だということです。しかしながら各「Fact」は、(ドメイン・)オブジェクトという「Truth」から導出されるのです。(ドメイン・)オブジェクトという「Truth」が確立しているからこそ、各「Fact」たるサブジェクトが一貫性を持って相互運用できる、、という訳です。
 
〜・〜
 
ただ、ここにもう一点認識を加えたいのです。
 
渡辺氏が主張するように、データモデル=オブジェクト=「Truth」を確立することが要であるということに異論はありません。渡辺氏の主張とやや異なるかもしれないのは、実作業的には、まずはドメインモデル=アプリケーション=サブジェクト=つまり個々の「Fact」を集めることからしか、「Truth」発見への道は開かれない、と考えることです。システムデザインに着手して最初に認知できるのは、雑多な「Fact」たちだけです。たくさんの「Fact」を集めて観察し、帰納的に統合することで、エンジニアの脳内にようやく「Truth」らしきものが生まれてきます。一旦*仮説*としての「Truth」を確立したら、その*仮説*で全ての「Fact」が演繹できるか、導出できるか、説明できるか、検証します。*仮説*たる「Truth」が無事全ての「Fact」を説明できたら、*仮説*を外すことができます。しかし、新たな「Fact」が出現したら??また*仮説*に逆戻りです。
 
そうなのです。揺るがないのは個々の「Fact」としてのサブジェクト=サブドメインの方なのです。対して、統合理論として構築された「Truth」=オブジェクト=データモデルは、常に仮説なのです
 
私は次のように思っています。
 
現在のRDB中心のアーキテクチャーでは、新たなFactの出現で直ぐに揺らぐような*仮説*を、Truthとして固くRDBに実装しなければならないことが、システムデザインの困難さの根源の一つではないだろうか?むしろ、個々の要求・要件を直接担っている境界付けられたコンテキスト=サブドメイン=サブジェクトの方が、Factとして揺らぎが少ない。よって、何かサブジェクト・セントリックな開発ができないだろうか?サブジェクト・セントリックにもかかわらず仮説たるTruthを表現、実現する方式が何かないだろうか?
 
◆以上