« チケット駆動開発によるチーム力向上の事例 #Redmine | トップページ | 日本のSIでは生産性を上げても、はかどっていないような仕事ぶりをする »

2014/06/01

第7回ドメイン駆動設計勉強会の感想 #dddosaka

第7回ドメイン駆動設計勉強会に参加してきた。
第4章「ドメインを隔離する」を皆で輪読して議論して、自分の浅い理解を深めることができて有意義だった。
議論した内容を質問回答形式で記載しておく。

【参考】
第7回ドメイン駆動設計読書会@大阪 - ドメイン駆動設計読書会@大阪 | Doorkeeper

vol7_20140601_事前疑問質問 ・ dddosaka/reading_ddd_report Wiki

[ 技術講座 ] Domain-Driven Designのエッセンス 第1回

[ 技術講座 ] Domain-Driven Designのエッセンス 第2回

[ 技術講座 ] Domain-Driven Designのエッセンス 第3回

[ 技術講座 ] Domain-Driven Designのエッセンス -目次-

【Q1】「ドメイン駆動設計は、伝統的ないくつかの考え方を基に、強調する点をずらしているのだ」という意味は?

【A1】伝統的な考え方はオブジェクト指向設計やデータモデリングなどの技法。
一方、ドメイン駆動設計は、それらを包含して、ドメインモデルをユビキタス言語で、ドメインエキスパートや開発者も共通理解できるような仕組みを提供する。

オブジェクト指向設計のように、オブジェクトの抽出とその関連に注力するのではなく、モデルの背後にあるドメイン(業務知識、ビジネスモデル)に注力する。

ドメイン駆動設計は、メタモデルのような感じ。
ソースコードで書かれた実装モデルだけでなく、その実装モデルは、ドメインという業務知識が埋め込まれて、ユビキタス言語という共通用語で表現される。

【Q2】「それによって道を外れることなく、折衷案を考え出すことができるのだ」という意味は?

【A2】ドメインエキスパートが描く分析モデルと開発者が実装する実装モデルの間にドメインモデルがある。
それらの折衷案である。

【Q3】P.66のレイヤ化アーキテクチャの図には「→」「△--」のような矢印がある。その意味は?

【A3】「→」は参照関係、「△--」は継承関係ではないか。

普通は、UI層→アプリケーション層→ドメイン層→インフラ層のように、上位レイヤが下位レイヤに依存する構造になる。
継承関係を使う場合は、例えば、ActiveRecordのように、インフラ層を継承したドメイン層があるだろう。
つまり、ORマッピングに関する処理はインフラ層にあるが、そのエンティティ特有の処理はドメイン層にある。
「インフラ層△--ドメイン層」の関係になる。

他に、ガジェットのように、「インフラ層△--UI層」の例もあるだろう。

別チームの議論では、上位レイヤが下位レイヤを継承する場合は、IoCを使いたい時があるらしい。
つまり、依存関係の逆転によって、下位レイヤが上位レイヤを呼び出すのではなく、上位レイヤが下位レイヤを呼び出すように、参照関係の向きを変える時に、継承関係を使う場合がある。

P.72の「アーキテクチャフレームワーク」でその内容の説明がある。
実装例としては、Javaのアノテーションが相当する。

Javaのアノテーションを使うフレームワークの例では、SeasarにおけるFormクラスのアノテーションによるValidatationチェック処理などがある。
RubyならMixinを使う事例もあるだろう。

Pythonにも同じような実装例があるらしい。

アーキテクチャフレームワークの失敗例としては、JavaのEJBがあるだろう。
ドメインオブジェクトをEJBとして実装すると、巨大な実装になりやすいし、ドメインを再利用しにくい。
しかも性能も悪い。

他の失敗例として、Hibernateもあげられていた。

【Q4】サービスクラスは、アプリケーション層なのか? ドメイン層なのか?

【A5】ドメイン駆動設計では、アプリケーション層のサービスもあれば、ドメイン層のサービスもあるし、インフラ層のサービスもある。
「サービス」の意味によって、存在するレイヤが異なる。

【Q5】ユースケースは、アプリケーション層なのか? ドメイン層なのか?

関西IT勉強会で聞いたとき、ドメイン駆動設計では、ユースケースはドメイン層に含まれると聞いた。

ドメイン駆動設計に出てくる「モデル」とは何ですか?~第28回関西IT勉強宴会の感想: プログラマの思索

【A5】Yes。
ユースケースは、ビジネスルールを表現するという意味で、ドメイン層に置かれる。
この点は、従来のオブジェクト指向設計とは違う観点になる。

【Q6】「アプリケーション層のレイヤは薄く保たれる」という意味は?

【A6】VBならコマンドボタンのFormクラス、StrutsならActionクラスがアプリケーション層に含まれることに相当する。
アプリケーション層は、UI層とドメイン層でデータをやり取りする場所であり、ビジネスロジックはドメイン層にへ委譲(Delegate)されるようにコーディングする。
これによって、ドメイン層が明確に分離されるだけでなく、凝集度も高まる。

【Q7】図4.1では、口座振り込み処理における資金振替クラスのCommitメソッドはアプリケーション層であるのに、注釈で「振り込みの引き落としが失敗したらトランザクションが失敗する」というビジネスルールが書かれている。
この内容は、ドメイン層で表現すべきではないか?

【A7】否。トランザクション処理は、アプリケーション層に配置すべき。
トランザクション処理の責務はアプリケーション層にある。

ただし、トランザクションの単位や粒度をどれくらいにすべきか、という点は、業務や方式設計に大きく依存する。
トランザクションの単位が大きければ、ロックがかかりやすく、処理も遅くなる。
トランザクションの単位が小さければ、障害が起きた時に、ロールバックやバッチのリランの手順が複雑になる。

【Q8】サーバー側から見れば、RIAはUI層だが、RIAのようなリッチクライアントでも、クライアント側にはドメイン層が含まれるか?

【A8】Yes。
クライアントにもMVCモデルを作ることはある。
Backborn.jsのように、クライアント側でJavaScript内にMVCモデルをコーディングする場合もある。
VBやC#のクライアントアプリも同様。
あるいは、Node.jsのように、サーバーサイドでクライアントアプリのドメインモデルを自動生成する場合もあるかもしれない。

クライアント側でドメイン駆動設計する場合、以下のような実装例もあるだろう。

・UI層=画面のコントロールボタンなど
・アプリ層=VBのFormクラスなど
・ドメイン層=画面表示する項目のValidationチェックなど

その場合、インフラ層は、JSONやXMLで表現されるデータになる。
つまり、インフラ層はサーバー側であり、HTTP通信でJSONPなりSOAP、RESTなどで、クライアントとデータをやり取りする。

この時、DBのトランザクション処理でCommitやRollbackがあるように、HTTP通信でもタイムアウト処理やセッション保持などのトランザクション処理が必要になる。
それらの処理はインフラ層に含まれ、ドメイン層は関知しない。

同様な事例として、複数の業務システムが連携するようなSOAもあるだろう。
例えば、販売管理システムと会計システムがSOA連携している場合があるだろう。
つまり、販売管理システムのインフラ層には、会計システムが含まれ、そのデータのやり取りは、SOAPメッセージによる通信処理になる。

すると、販売管理システムのドメインと会計システムのドメインは、使われるユビキタス言語が異なる。
すなわち、それぞれのドメインのコンテキストは異なる。
販売管理のドメインと会計のドメインは「コンテキストマップ」に配置され、それぞれのドメインは「境界づけられたドメイン」で区別される。

この発想は、System of Systems にもつながるだろう。
各ドメインは一つのサブシステムとして独自で動作し、そのサブシステム同士が関連して一つの大きなシステムをなす。
以下のWebページでは、System of Systemsの例として、デジタルカメラとカラープリンタを統合した家電製品があげられている。
最近なら、車載機器などの組み込み機器、IoTのようにネットワーク機能を持つ家電製品の部品、複数の業務を統合パッケージ製品として売り出すERPも相当するだろう。

System of Systems : システムオブシステムズとは: システム思考xデザイン思考xマネジメントで自己成長

System of Systemsの各サブシステムは「境界づけられたドメイン」として区別され、サブシステム同士が関連した一つのシステムは「コンテキストマップ」になる。
「コンテキストマップ」の中に、それぞれのサブシステムの関係が表現されている。

【Q9】「ドメイン駆動設計が最も効果があるのは、大掛かりなプロジェクトに対してである」という意味は?

「大掛かりなプロジェクト」の対象は、大規模プロジェクトだけでない、という意見があった。
ドメインの複雑度の観点もあるだろう。
また、当初は単純なドメインであっても、ライフサイクルの長い業務であれば、運用するうちに改善要望がどんどん反映されてドメインが複雑になっていく場合もあるだろう。

その場合、第4部以降では、そのような大規模なプロジェクトにおけるドメイン駆動設計のパターンとして、「腐敗防止層」「コアドメイン」「蒸留」などがあげられている。
例えば、大規模プロジェクトにおいて、モデルの整合性を維持するために、複雑なインフラ層の間に腐敗防止層というI/Fを配置してドメインモデルを隔離したりする。

【Q10】「利口なUI」と「トランザクションスクリプト」の違いは何か?

「利口なUI」は、UI層にビジネスロジックを埋め込んでしまい、ドメインモデルを抽出していないアンチパターン。
「トランザクションスクリプト」は、アプリケーション層にビジネスロジックを埋め込んでしまい、ドメインモデル貧血症になってしまうアンチパターン。
すなわち、両方ともドメインモデル貧血症だが、その症状のレイヤが異なる。

「利口なUI」の解決パターンとしては、ドメインモデルを分離するだけでなく、「レイヤ化アーキテクチャ」を用いて、アプリケーション層にドメインモデルを委譲する「トランザクションスクリプト」もある。

【感想】
最近、ドメイン駆動設計が注目を浴びる理由は、クラウド技術が普及したことによって、業務システムの移植性の品質要求が高まったこともあるだろうと考える。
クラウドにある業務システムは、サーバーというハードウェアに依存せず、どのサーバーでも移植できなければならない。
すると、ドメイン駆動設計の思想で構築された業務システムならば、ドメインモデルが隔離されているので、クラウド環境というインフラ層を変えても、簡単に移植できて、稼働できるようになるはずだ。

その意味では、クラウド技術とドメイン駆動設計は相性が良いのではないか。

【まとめ】
僕は、ドメイン駆動設計が実現されたシステム設計の経験はない。
だから、ドメイン駆動設計は、いつも桃源郷、理想郷のように感じる。

本来あるべき業務モデルの設計は、ドメイン駆動設計なのだ、と思うが、そのために必要な手法が自分の頭で把握できていない。
今後も勉強会で議論してみる。

【追記】
Twitter / akipii: ドメイン知識が顧客でなくSIに流れていくのも凄く同感。@kawakawaさんによるドメイン駆動設計読書会@大阪第6回までの感想とドメイン駆動設計の基本についてのまとめ http://goo.gl/Lv71Xd #dddosaka

Twitter / akipii: 日本ではSIの方が顧客よりドメインエキスパートになる時がある指摘は凄く同感 @kawakawa さんによるドメイン駆動設計読書会@大阪第6回までの感想とドメイン駆動設計の基本についてのまとめ http://goo.gl/Lv71Xd #dddosaka

|

« チケット駆動開発によるチーム力向上の事例 #Redmine | トップページ | 日本のSIでは生産性を上げても、はかどっていないような仕事ぶりをする »

モデリング」カテゴリの記事

経済学・ERP・財務会計」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



« チケット駆動開発によるチーム力向上の事例 #Redmine | トップページ | 日本のSIでは生産性を上げても、はかどっていないような仕事ぶりをする »