わんくま同盟 大阪勉強会 #60 
C#実装から見る DDD(ドメイン駆動設計)Ver2.0 (ちょっと追記版) 
By @kawakawa
わんくま同盟 大阪勉強会 #60 
はじめに 
みなさん、 
DDDをご存じでしょうか?
わんくま同盟 大阪勉強会 #60 
はじめに 
DDDとは、2011年に日本で出版され た「ドメイン駆動設計」の事です。
わんくま同盟 大阪勉強会 #60 
はじめに 
DDDは書籍以外にも、ネット上に多数 の資料があり、目にされた方も多いか と思います。
わんくま同盟 大阪勉強会 #60 
はじめに 
しかし、DDDは理屈の理解はできても、 
実践するのは、難しいと思います。 
まず、 
顧客(ドメインエキスパート)が要ります。 
仲間(開発チーム)が要ります。 
プログラム知識が要ります。 
・・・・
わんくま同盟 大阪勉強会 #60 
はじめに 
本日は、DDDをプログラム実装という 
観点から見てみることで、 
DDDを知らない人には、興味のキッカケを、 
DDDの実装をしらない人には、一例を提 示できればと思いました。 
それではみなさん、よろしくお願いします。
わんくま同盟 大阪勉強会 #60 
自己紹介 
•かわべ たくや 
•Twitter:@kawakawa 
•大阪で働いています 
•I Love C#! 
•DDD勉強中!
わんくま同盟 大阪勉強会 #60 
はじめに 
DDDを知らなくても、困らないような資料に したつもりですが、やっぱり知らないより、 知っていたほうが楽しいので、簡単にDDD を説明させて頂きます。
わんくま同盟 大阪勉強会 #60 
DDD知らない方向け 「DDDとは?」 (独断と偏見で説明)
わんくま同盟 大阪勉強会 #60 
DDDとは? 
•DDDとは、「Domain-Driven-Design」 
•訳すと、「ドメイン駆動設計」 
•よく目にする、●DD「●-Driven- Development」は、「●駆動“開発”」 であり、「●駆動“設計”」と異なります。
わんくま同盟 大阪勉強会 #60 
DDDとは? 
•ドメインとは、「領域」の意味。 
(顧客のお仕事=「業務領域」であり、これも 1つのドメインです) 
•ドメインから問題・関心ごとを抜き出し たのが「(ドメイン)モデル」。 
•プログラマのお仕事は、この「モデル」 をプログラムで実装することです。
わんくま同盟 大阪勉強会 #60 
DDDとは? 
•開発は、モデルを「分析」「設計」「実 装」のサイクルをグルグル回します。 
(モデル駆動開発と呼ばれてます) 
•ドメイン駆動“設計”とは、そのグルグル 回すことを如何に継続させるか設計す ることです。
わんくま同盟 大阪勉強会 #60 
DDDとは? 
•よくある勘違いとしては、DDD本自体 にモデルの答えは書いていません。 (モデリングの本ではないです) 
•モデリングを継続させる方法を考える 本です。 
(魚をくれるのではなく、釣り方を教えてくれる本)
わんくま同盟 大阪勉強会 #60 
DDDを行う意義とは?
わんくま同盟 大阪勉強会 #60 
DDDの意義 
私が思うDDDの意義は、 
・DDD本を読むまで 
「動くアプリが正義!」 
・DDD本を読んだ後 
「動き続けるアプリが正義!」 
アプリへの認識が変わりました。 
(※動く=顧客の問題を解決すると読み替えてもOK) 
(※動く≒顧客の問題を解決する)
わんくま同盟 大阪勉強会 #60 
DDDの意義 
動き続けるとは? 
•業務システムで考えると、納品は、開発の終わりで はありません。納品してからも開発は続きます。 
(有償・無償は問わず) 
•顧客から要望は色々出てきます。 
「より見やすい画面が欲しい」 
「より操作しやすくして欲しい」 
•顧客の業務形態に変化が生ずれば、仕様変更です。
わんくま同盟 大阪勉強会 #60 
DDDの意義 
つまり、動き続けるとは、 
変化し続けるという事。 
どこまで、仕様変更に追随できますか?
わんくま同盟 大阪勉強会 #60 
DDDの意義 
つまり、動き続けるとは、 
変化し続けるという事。 
どこまで、仕様変更に追随できますか? 
※勿論、業務形態が根本的に変化したのなら、追随は 無理です。 (不動産屋が八百屋にジョブチェンジなど)
わんくま同盟 大阪勉強会 #60 
DDDの意義 
また、DDDに向かない場合もあります。 
•ドメインが薄い 
(DDD行うほうが労力かかります) 
•アプリの使用期間が短い 
(一度きりで再利用しない場合。デモアプリなど)
わんくま同盟 大阪勉強会 #60 
DDDの面白い所
わんくま同盟 大阪勉強会 #60 
DDDの面白い所 
DDDでは、モデルは実装されて初めて意味を成 すと考えられています。 
つまり、図やUMLがモデルではなく、動くソフト ウェアまで含めて、モデルと考えられています。
わんくま同盟 大阪勉強会 #60 
DDDの面白い所 
プログラミングにおいて大抵は、実装上の制約 (性能や品質等々)により、設計図通りに実装出 来ないものですが、そう言った点も含めて、絵に かいた餅ではなく、動くモデルに注力しているの が、非常に現実的で、DDDは面白い思想だと思 いました。
わんくま同盟 大阪勉強会 #60 
それでは、DDDの実装を見てみましょう
わんくま同盟 大阪勉強会 #60 
とその前に・・・ 
いきなりですが、DDDは実装も大事ですが、実 装以外の項目も大事です。 
•顧客(ドメインエキスパート)とのコミュニケーション 
•コンテンツマップ作成 
•ユビキタス言語の発見 
•開発チームづくり ・・・などなど。 
残念ながら、実装だけ見ても“DDD”はできません…。
わんくま同盟 大阪勉強会 #60 
DDD実装のサンプル元 
•実装サンプルは、DDD本:著者エヴァンスも関わった「DDD Sample」使います。 
•http://dddsample.sourceforge.net/ 
•DDD本にはそこまで詳しく触れられていなかった、DDDの実 装方法が詰まっていて大変参考になります。
わんくま同盟 大阪勉強会 #60 
DDD実装のサンプル元 
•注意点としては、DDDSampleはDDD本を読んでいる事を前 提されています。 
•内容は、DDD本に何度も出てくる、貨物輸送プログラムです。 
•HPにクラス設計図等の説明が無いので、本を読まないと、 「これは何クラス?」という状況に陥ります。
わんくま同盟 大阪勉強会 #60 
実装例一覧 
本日提示させて頂く、実装例は、 
•レイヤ化アーキテクチャ (少しだけ責務のレイヤも) 
•値オブジェクト 
•エンティティ 
•リポジトリ
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
ソフトウェアの世界には、レイヤという便利な考 え方があります。 
有名なレイヤーといえば、MVC(Model View Controller)ですよね。 
一番不安定なView層から、Model層を直接参 照・編集できないように切り離すことで、Model 層が安定します。 (MVCが指すModelとDDDのモデルは微妙に異なります)
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
DDDのレイヤ化アーキテクチャも考え方は、同 じです。 
(ドメイン)モデルを様々な事象から可能な限り 切り離すことで、モデルの安定化を目指します。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
DDD本「第4章ドメインを隔離する」から抜粋 
基本的に、上のレイヤは下位レイヤーを参照できるが、 
逆に下から上へは参照できない構造。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
ユーザインタフェース(またはプレ ゼンテーション層) 
•ユーザに情報を表示して、ユーザのコマン ドを解釈する責務を負う。 
•外部アクタは人間のユーザではなく、別の コンピュータシステムのこともある。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
アプリケーション層 
•ソフトウェアが行うことになっている仕事を 定義し、表現力豊かなドメインオブジェクト が問題を解決するように導く。 
•このレイヤが責務を負う作業は、ビジネス にとって意味があるものか、あるいは他シ ステムのアプリケーション層と相互作用す るのに必要なものである。このレイヤは薄 く保たれる。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
ドメイン層(またはモデル層) 
•ビジネスの概念と、ビジネスが置かれた状 況に関する情報、およびビジネスルールを 表す責務を負う。 
•ビジネスの状況を反映する状態はここで 制御され使用されるが、それを格納すると いう技術的な詳細は、インフラストラクチャ に委譲される。この層がビジネスソフトウェ アの核心である。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
インフラストラクチャ層 
•上位のレイヤを支える一般的な技術的機 能を提供する。これには、アプリケーション のためのメッセージ送信、ドメインのため の永続化、ユーザインタフェースのための ウィジェット描画などがある。 
•インフラストラクチャ層は、ここで示す4 層 間における相互作用のパターンも、アーキ テクチャフレームワークを通じてサポート することがある。 
•個人的感想としては、ここは「ごった煮」層。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
それでは、早速実装をみてみましょう。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
名前空間(フォルダ分け)などを使って、レイヤ分類を実装してい ました。 
MVCもフォルダで分けたりす るので、同じですね。 DDDSampleでは他にもフォ ルダがありますが、ここでは 解りやすくする為、省いてい ます。
わんくま同盟 大阪勉強会 #60 
レイヤ化アーキテクチャ 
レイヤ化自体は、フォルダ(名前空間)分けという 単純な方法でした。 
しかし、MVC同様にどのオブジェクトはどのフォル ダに格納すべきか、よく考える必要があります。
わんくま同盟 大阪勉強会 #60 
少しだけ、 責務のレイヤ
わんくま同盟 大阪勉強会 #60 
責務のレイヤ 
•DDDSampleには直接記されていないのです が、DDDには、「責務のレイヤ」というレイヤ概 念があります。 
•モデル層内部をより細かく分類して、不安定 箇所(仕様変更が多発する箇所)を切り離しま す。
わんくま同盟 大阪勉強会 #60 
責務のレイヤ 
第16章 大規模な構造「責務のレイヤ」より
わんくま同盟 大阪勉強会 #60 
責務のレイヤ 
•責務のレイヤは、開発に非常に有効な手段と思いま す。 
•しかし、責務のレイヤを実装するには、顧客(ドメイン エキスパート)の知識が必要となり、上流設計で行う 作業やスキルが必要となります。 
・業務知識の習得 
・業務の見える化 ・・・色々 
やはり、一筋縄ではいかなそうです。
わんくま同盟 大阪勉強会 #60 
値オブジェクト
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
•DDDでは、如何にモデルをシンプルに保つか が、大切な考えになります。 
•オブジェクトに、責務以上の機能、余計なデー タを持たせない事に、注意を払います。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
•値オブジェクトは、“属性情報”だけを持ちます。 
•属性情報とは、「色」や「大きさ」など、 対象の性質を表したものです。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
そして、値オブジェクトは次のルールが適応され ます。 
•同一性(アイデンティティ)を持たない。 
•不変(immutable)である。 
(属性に変更が必要になった場合、属性を変更するのではなく、 新しい属性を持った値オブジェクトを作成する)
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
DDDSampleのLeg(行程)をサンプルにして、実装を みてます。 
Legは船の貨物の「積み込む地点」と、「荷下ろし地点」 を保持します。 
※ 単純化の為、DDDSampleから改変(省略)しています
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
//値オブジェクト用インターフェース 
public interface IValueObject<T> 
{ 
//属性が同じかチェック 
bool SameValueAs(T other); 
} 
最初に、値オブジェクト用のインターフェースを用意。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
//Leg(行程)の値オブジェクト実装 
public class Leg : IValueObject<Leg> 
{ 
public Location LoadLocation { get; private set; } //荷積み地点 
private Location UnloadLocation { get; private set; } //荷下ろし地点 
public Leg(Location loadLocation, Location unloadLocation) 
{ 
this.LoadLocation = loadLocation; 
this.UnloadLocation = unloadLocation; 
} 
public bool SameValueAs(Leg other) 
{ 
if (this.LoadLocation != other.LoadLocation) return false; 
if (this.UnloadLocation != other.UnloadLocation) return false; 
return true; 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
•Leg(行程)サンプルの特徴は、属性として、 
・ LoadLocation(荷積み地点) 
・ UnloadLocation(荷下ろし地点) 
を持ち、コンストラクタ以外に、属性を変更する 手段を持ちません。 
•このLeg(行程)だけみると、値オブジェクトと 言っても、特別なことは無いように見えますね。
わんくま同盟 大阪勉強会 #60 
値オブジェクト その2
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
•次は、Leg(行程)をリストとして保持する、Itinerary(運送スケジュール)オブジェクトを考えてみます。 
•Itineraryは、Cargo(貨物)(後述するエンティティ)の Legをまとめたもので、Legリスト最初が出発点、最 後が到着点(目的地)となります。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
このItinerary(運送スケジュール)を値オブジェク トと考えた場合、不変性をどう考えればよいで しょうか? 
リストとして保持しているLeg(行程)に、1つでも 変更が生じた場合、Cargo(貨物)は、Itinerary(運送スケジュール)を破棄して、都度、新しいイ ンスタンスを用意しないといけないのでしょう か?
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
DDD本の第16章『大規模な構造』の「責務のレイヤ」に、 次のように書かれています。 
ソフトウェアにおけるこのレイヤは、計画作成と意思決 定に用いるツールをユーザに提供し、潜在的には一部 の意思決定を自動化できる 
(運送スケジュールが変更になった時、自動的に貨物 の経路を選択し直すなど) 
つまり、意思決定支援レイヤの責務として、変更対応 すればよいそうです。(うーん難しい!)
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
個人的解釈としては、 
•運送スケジュール変更というのは、Cargo(貨物)自 体の責務ではない。 
•スケジュール変更は、より上位の意思に寄るもので ある。(例:貨物運送担当者など) 
•その為、 RoutingService(経路選択サービス)を用 意し、スケジュール変更に伴う実装的負担を引き受 けることで、各オブジェクト構造をシンプルに保てる (余計な仕事をさせなくて済む)
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
•まずは、Itinerary(運送スケジュール)の実装 をみてみましょう。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
// Itinerary(運送スケジュール)オブジェクト 
public class Itinerary : IValueObject<Itinerary> 
{ 
private List<Leg> legs = null; 
public Itinerary(List<Leg> legs) 
{ 
this.legs = legs; 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
Itinerary(運送スケジュール)は、単純にLeg(行 程)をリストで保持しているだけですね。 
次は、Cargo(貨物)とRoutingService(経路選 択サービス)です。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
// Cargo(貨物) (後ページのエンティティ時にも記載) 
public class Cargo:IEntity 
{ 
~省略~ 
//運送スケジュール 
private Itinerary itinerary; 
//運送スケジュール変更 
public void AssignToRoute(Itinerary itinerary) 
{ 
this.itinerary = itinerary; 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
// Itinerary(運送スケジュール)を新しく作るサービスを用意 
public class RoutingService 
{ 
public List<Itinerary> fetchRoutesForSpecification(Cargo cargo) 
{ 
//新しいltinerary(運送スケジュール)割り当て 
cargo.assignToRoute(toItinerary()); 
} 
//条件に従い、新しい運送スケジュール作成 
private Itinerary toItinerary() { 
~省略~ 
return new Itinerary(legs); 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
値オブジェクト 
DDDSampleにおける実際のRoutingService(経路選択サービス)はもっと複雑です。 
ただ、DDD的意図を読み取ると、経路変更の仕 事を、経路情報を持つCargo(貨物)に行わせる のではなく、Serviceとして外部に出したことによ り、Carg(貨物)がシンプルに保たれている事に、 意義があるのと考えています。
わんくま同盟 大阪勉強会 #60 
エンティティ
わんくま同盟 大阪勉強会 #60 
エンティティ 
•エンティティは値オブジェクトと異なり、同一性 (アイデンティティ)を持ちます。 
•同一性は、モデルのライフサイクル期間中保 たれます。 
•同一性は、エンティティをDB格納して、取り出 した後でも、保たれます。 
エンティティ 
モデルのライフライン 
DB 
エンティティ 
同じアイデンティティ
わんくま同盟 大阪勉強会 #60 
エンティティ 
•cargo(貨物)をサンプルに、エンティティの実 装を見てみます。 
•cargo(貨物)は、TrackingId(追跡ID)をアイ デンティティとして、同一性を持ちます。 
•TrackingId(追跡ID)は、作成時に割り当てら れた後、変更されることはありません。
わんくま同盟 大阪勉強会 #60 
エンティティ 
// エンティティ用インターフェース 
interface IEntity<T> 
{ 
//同一エンティティかチェック 
bool sameIdentityAs(T other); 
} 
•まずはエンティティ用のインターフェース
わんくま同盟 大阪勉強会 #60 
エンティティ 
//cargo(貨物) 
public class Cargo:IEntity<Cargo> 
{ 
private readonly TrackingId trackingId; 
public Cargo(TrackingId trackingId) { 
this.trackingId = trackingId; 
} 
public bool SameIdentityAs(Cargo other) 
{ 
return other != null && trackingId.sameValueAs(other.trackingId); 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
エンティティ 
•アイデンティティであるtrackingId(追跡ID)を readonlyにすることで、設定後の不意な変更 を防止しています。 
•それ以外は特段特徴のない、普通のクラスで すね。
わんくま同盟 大阪勉強会 #60 
エンティティ 
•次に、そのアイデンティティとして使用されてい る TrackingId(追跡ID)の実装を見てみます。
わんくま同盟 大阪勉強会 #60 
エンティティ 
// TrackingId(追跡ID) 
public sealed class TrackingId : IValueObject<TrackingId> 
{ 
private readonly String id; 
public TrackingId(String id) { 
this.id = id; 
} 
public override bool Equals(object o) { 
if (this == o) return true; 
if (o == null) return false; 
TrackingId other = (TrackingId)o; 
return SameValueAs(other); 
} 
public bool SameValueAs(TrackingId other) { 
return other != null && this.id.Equals(other.id); 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
エンティティ 
•驚いた事に、 TrackingId(追跡ID)は値オブ ジェクトです。 
•Cargo(貨物)は、エンティティですが、そのア イデンティティとして、値オブジェクトである TrackingId(追跡ID)を使用しています。
わんくま同盟 大阪勉強会 #60 
エンティティ 
これらの事から、何が値オブジェクトで、エンティ ティなのか、深く考える必要があることが伺えま す。 
(エンティティのアイデンティティも、普通ならエンティティになると 普通思うと思います) 
個人的には、容易にオブジェクトをエンティティと しないという、強い意志を感じました。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
•エンティティの実装例で見た通り、同一性の確 保は、プログラムの実装に依存します。 (例では、追跡IDのユニーク性確保など) 
•このように、新しくオブジェクトをnew(インスタ ンス化)したいときに、特定条件(今回は追跡 ID採番)を実行したい事は多々あります。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
•そこで、オブジェクトの生成、並びにDBへの格 納・取り出しなど、オブジェクト化するのに必要 な処理をまとめたのが、「Factories(ファクト リ)」と「Repositories(リポジトリ)」です。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
•「Factories」がオブジェクト生成時に使用。 
•「Repositories」は、DB格納や取り出しなど、 オブジェクトを使いまわす時に使用します。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
•cargo(貨物)を格納するCargoRepositoryの 実装例は次のようになります。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
//貨物リポジトリ 
interface ICargoRepository 
{ 
//指定、追跡IDに該当するcargo取得 
Cargo find(TrackingId trackingId); 
//全cargoを取得 
List<Cargo> findAll(); 
//DBに格納します 
void store(Cargo cargo); 
//DBなどのシーケンスを使い、ユニークなIDを発番させます。 
TrackingId nextTrackingId(); 
}
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
•ICargoRepositoryインターフェースを実装す ることで、O/Rマッパで実装するとDBに結びつ けたり、ファイル操作で実装すると、Textファイ ルとして保存させたり、することができます。 
•次ページはDBで実装した時の例です。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
//貨物リポジトリ(DB) 
public class CargoRepositoryDb 
{ 
private DAO dao=null; 
//指定、追跡IDに該当するcargo取得 
public Cargo find(TrackingId tid) { 
dao.createQuery("from Cargo where trackingId = :tid"); //SQL 
dao.setParameter("tid", tid); 
return dao.result(); 
} 
//全cargoを取得 
public List<Cargo> findAll() { 
dao.createQuery("from Cargo "); //SQL 
return dao.result(); 
} 
(続く) 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
(続き) 
// DBに格納します 
public void store(Cargo cargo){ 
dao.saveOrUpdate(cargo); 
dao.createSQLQuery("delete from Leg where cargoId =null").executeUpdate(); 
} 
// ユニークなIDを発番 
public TrackingId nextTrackingId() { 
var randomId= dao.GetRoundomUID(); 
return new TrackingId(randomId); 
} 
} 
※ 解りやすくする為に、DDDSampleから改変しています。
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
Factoriesの実装例は載せておりませんが、 Repositoriesとほぼ同じような実装内容になりま す。 
そうなってくると、FactoriesとRepositoriesをま とめても良さそうに思いますよね?
わんくま同盟 大阪勉強会 #60 
Factories と Repositories 
しかし、DDD本では、次の理由でFactoriesと Repositoriesの役割を分離させてます。 
•Factoriesは、新しいオブジェクトを生成する責務。 
•Repositoriesは、既存オブジェクトを再構成する責務。 
•分離させることで、FactoriesをDB(永続)化する処 理から分離できる。
わんくま同盟 大阪勉強会 #60 
まとめ
わんくま同盟 大阪勉強会 #60 
まとめ 
簡単な実装例だけでしたが、 
•レイヤ化アーキテクチャ 
•値オブジェクト 
•エンティティ 
•Repositories 
DDDの中核をなす、実装例を見て頂きました。
わんくま同盟 大阪勉強会 #60 
まとめ 
他にもDDDSampleでは、 
•集約(Aggregate) 
•ドメインイベント 
•Service 
•仕様(SPECIFICATION) 
などの実装例が紹介をされています。 
(しかし、これらはDDDを知らないと、判りづらいかもしれませ ん)
わんくま同盟 大阪勉強会 #60 
書籍紹介 
次に、DDD実装で参考になる書籍を簡単に紹介させて いただきたいと思います。
わんくま同盟 大阪勉強会 #60 
書籍紹介 
ドメイン駆動 
■amazon 
http://www.amazon.co.jp/dp/4798116173 
■書籍紹介 
C#を使った、ドメイン駆動設計をパターンを使って 実装していく実践本です。 
まさに、C#er向けの一冊。 
C#2.0と若干古いのですが、サンプルソースは参 考になります。 
SQLServerと如何に連携させるか、 
テスト駆動開発でいかに進めるかなど、 
てんこ盛りな内容です。(少々詰め込み過ぎ?)
わんくま同盟 大阪勉強会 #60 
書籍紹介 
Implementing Domain-Driven Design 
■amazon 
http://amzn.com/0321834577 
■書籍紹介 
英語本ですが、IDDDというキーワードでよく見かける、 DDD実践本です。 
DDD本の後に出版された、如何にDDDを実践してい くかを主眼に書かれている本で、DDD本には収録さ れていなかったドメインイベントも記載されているよう です。 
DDD本に劣らない分厚さを誇ります(汗。 
私は当然、英語苦手なので未読です(汗汗 
IDDDのワークショップを世界的に行うコミュニティがあ るようです。(http://idddworkshop.com/)
わんくま同盟 大阪勉強会 #60 
まとめ 
最初にも書かさせて頂きましたが、DDDにお ける実装が占める役割は、ほんの一部です。 
実装に至るまでの過程がもの凄く重要だと思い ます。 
また、実装例として挙げたものより、状況に よって、より適切な実装方法は、数多くあると思 います。
わんくま同盟 大阪勉強会 #60 
まとめ 
今回は、実装という方面からDDDを眺めてみ ましたが、DDDを知らなかった方に、少しでも興 味を持って頂けたのなら幸です。 
DDDの実装については、私も勉強中です。 
もし気になる点などありましたら、是非お声かけ 下さい。<(_ _)>ペコリ
わんくま同盟 大阪勉強会 #60 
まとめ 
以上、ご清聴ありがとうございました。

C#実装から見るDDD(ドメイン駆動設計)

  • 1.
    わんくま同盟 大阪勉強会 #60 C#実装から見る DDD(ドメイン駆動設計)Ver2.0 (ちょっと追記版) By @kawakawa
  • 2.
    わんくま同盟 大阪勉強会 #60 はじめに みなさん、 DDDをご存じでしょうか?
  • 3.
    わんくま同盟 大阪勉強会 #60 はじめに DDDとは、2011年に日本で出版され た「ドメイン駆動設計」の事です。
  • 4.
    わんくま同盟 大阪勉強会 #60 はじめに DDDは書籍以外にも、ネット上に多数 の資料があり、目にされた方も多いか と思います。
  • 5.
    わんくま同盟 大阪勉強会 #60 はじめに しかし、DDDは理屈の理解はできても、 実践するのは、難しいと思います。 まず、 顧客(ドメインエキスパート)が要ります。 仲間(開発チーム)が要ります。 プログラム知識が要ります。 ・・・・
  • 6.
    わんくま同盟 大阪勉強会 #60 はじめに 本日は、DDDをプログラム実装という 観点から見てみることで、 DDDを知らない人には、興味のキッカケを、 DDDの実装をしらない人には、一例を提 示できればと思いました。 それではみなさん、よろしくお願いします。
  • 7.
    わんくま同盟 大阪勉強会 #60 自己紹介 •かわべ たくや •Twitter:@kawakawa •大阪で働いています •I Love C#! •DDD勉強中!
  • 8.
    わんくま同盟 大阪勉強会 #60 はじめに DDDを知らなくても、困らないような資料に したつもりですが、やっぱり知らないより、 知っていたほうが楽しいので、簡単にDDD を説明させて頂きます。
  • 9.
    わんくま同盟 大阪勉強会 #60 DDD知らない方向け 「DDDとは?」 (独断と偏見で説明)
  • 10.
    わんくま同盟 大阪勉強会 #60 DDDとは? •DDDとは、「Domain-Driven-Design」 •訳すと、「ドメイン駆動設計」 •よく目にする、●DD「●-Driven- Development」は、「●駆動“開発”」 であり、「●駆動“設計”」と異なります。
  • 11.
    わんくま同盟 大阪勉強会 #60 DDDとは? •ドメインとは、「領域」の意味。 (顧客のお仕事=「業務領域」であり、これも 1つのドメインです) •ドメインから問題・関心ごとを抜き出し たのが「(ドメイン)モデル」。 •プログラマのお仕事は、この「モデル」 をプログラムで実装することです。
  • 12.
    わんくま同盟 大阪勉強会 #60 DDDとは? •開発は、モデルを「分析」「設計」「実 装」のサイクルをグルグル回します。 (モデル駆動開発と呼ばれてます) •ドメイン駆動“設計”とは、そのグルグル 回すことを如何に継続させるか設計す ることです。
  • 13.
    わんくま同盟 大阪勉強会 #60 DDDとは? •よくある勘違いとしては、DDD本自体 にモデルの答えは書いていません。 (モデリングの本ではないです) •モデリングを継続させる方法を考える 本です。 (魚をくれるのではなく、釣り方を教えてくれる本)
  • 14.
    わんくま同盟 大阪勉強会 #60 DDDを行う意義とは?
  • 15.
    わんくま同盟 大阪勉強会 #60 DDDの意義 私が思うDDDの意義は、 ・DDD本を読むまで 「動くアプリが正義!」 ・DDD本を読んだ後 「動き続けるアプリが正義!」 アプリへの認識が変わりました。 (※動く=顧客の問題を解決すると読み替えてもOK) (※動く≒顧客の問題を解決する)
  • 16.
    わんくま同盟 大阪勉強会 #60 DDDの意義 動き続けるとは? •業務システムで考えると、納品は、開発の終わりで はありません。納品してからも開発は続きます。 (有償・無償は問わず) •顧客から要望は色々出てきます。 「より見やすい画面が欲しい」 「より操作しやすくして欲しい」 •顧客の業務形態に変化が生ずれば、仕様変更です。
  • 17.
    わんくま同盟 大阪勉強会 #60 DDDの意義 つまり、動き続けるとは、 変化し続けるという事。 どこまで、仕様変更に追随できますか?
  • 18.
    わんくま同盟 大阪勉強会 #60 DDDの意義 つまり、動き続けるとは、 変化し続けるという事。 どこまで、仕様変更に追随できますか? ※勿論、業務形態が根本的に変化したのなら、追随は 無理です。 (不動産屋が八百屋にジョブチェンジなど)
  • 19.
    わんくま同盟 大阪勉強会 #60 DDDの意義 また、DDDに向かない場合もあります。 •ドメインが薄い (DDD行うほうが労力かかります) •アプリの使用期間が短い (一度きりで再利用しない場合。デモアプリなど)
  • 20.
  • 21.
    わんくま同盟 大阪勉強会 #60 DDDの面白い所 DDDでは、モデルは実装されて初めて意味を成 すと考えられています。 つまり、図やUMLがモデルではなく、動くソフト ウェアまで含めて、モデルと考えられています。
  • 22.
    わんくま同盟 大阪勉強会 #60 DDDの面白い所 プログラミングにおいて大抵は、実装上の制約 (性能や品質等々)により、設計図通りに実装出 来ないものですが、そう言った点も含めて、絵に かいた餅ではなく、動くモデルに注力しているの が、非常に現実的で、DDDは面白い思想だと思 いました。
  • 23.
    わんくま同盟 大阪勉強会 #60 それでは、DDDの実装を見てみましょう
  • 24.
    わんくま同盟 大阪勉強会 #60 とその前に・・・ いきなりですが、DDDは実装も大事ですが、実 装以外の項目も大事です。 •顧客(ドメインエキスパート)とのコミュニケーション •コンテンツマップ作成 •ユビキタス言語の発見 •開発チームづくり ・・・などなど。 残念ながら、実装だけ見ても“DDD”はできません…。
  • 25.
    わんくま同盟 大阪勉強会 #60 DDD実装のサンプル元 •実装サンプルは、DDD本:著者エヴァンスも関わった「DDD Sample」使います。 •http://dddsample.sourceforge.net/ •DDD本にはそこまで詳しく触れられていなかった、DDDの実 装方法が詰まっていて大変参考になります。
  • 26.
    わんくま同盟 大阪勉強会 #60 DDD実装のサンプル元 •注意点としては、DDDSampleはDDD本を読んでいる事を前 提されています。 •内容は、DDD本に何度も出てくる、貨物輸送プログラムです。 •HPにクラス設計図等の説明が無いので、本を読まないと、 「これは何クラス?」という状況に陥ります。
  • 27.
    わんくま同盟 大阪勉強会 #60 実装例一覧 本日提示させて頂く、実装例は、 •レイヤ化アーキテクチャ (少しだけ責務のレイヤも) •値オブジェクト •エンティティ •リポジトリ
  • 28.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ
  • 29.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ ソフトウェアの世界には、レイヤという便利な考 え方があります。 有名なレイヤーといえば、MVC(Model View Controller)ですよね。 一番不安定なView層から、Model層を直接参 照・編集できないように切り離すことで、Model 層が安定します。 (MVCが指すModelとDDDのモデルは微妙に異なります)
  • 30.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ DDDのレイヤ化アーキテクチャも考え方は、同 じです。 (ドメイン)モデルを様々な事象から可能な限り 切り離すことで、モデルの安定化を目指します。
  • 31.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ DDD本「第4章ドメインを隔離する」から抜粋 基本的に、上のレイヤは下位レイヤーを参照できるが、 逆に下から上へは参照できない構造。
  • 32.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ ユーザインタフェース(またはプレ ゼンテーション層) •ユーザに情報を表示して、ユーザのコマン ドを解釈する責務を負う。 •外部アクタは人間のユーザではなく、別の コンピュータシステムのこともある。
  • 33.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ アプリケーション層 •ソフトウェアが行うことになっている仕事を 定義し、表現力豊かなドメインオブジェクト が問題を解決するように導く。 •このレイヤが責務を負う作業は、ビジネス にとって意味があるものか、あるいは他シ ステムのアプリケーション層と相互作用す るのに必要なものである。このレイヤは薄 く保たれる。
  • 34.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ ドメイン層(またはモデル層) •ビジネスの概念と、ビジネスが置かれた状 況に関する情報、およびビジネスルールを 表す責務を負う。 •ビジネスの状況を反映する状態はここで 制御され使用されるが、それを格納すると いう技術的な詳細は、インフラストラクチャ に委譲される。この層がビジネスソフトウェ アの核心である。
  • 35.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ インフラストラクチャ層 •上位のレイヤを支える一般的な技術的機 能を提供する。これには、アプリケーション のためのメッセージ送信、ドメインのため の永続化、ユーザインタフェースのための ウィジェット描画などがある。 •インフラストラクチャ層は、ここで示す4 層 間における相互作用のパターンも、アーキ テクチャフレームワークを通じてサポート することがある。 •個人的感想としては、ここは「ごった煮」層。
  • 36.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ それでは、早速実装をみてみましょう。
  • 37.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ 名前空間(フォルダ分け)などを使って、レイヤ分類を実装してい ました。 MVCもフォルダで分けたりす るので、同じですね。 DDDSampleでは他にもフォ ルダがありますが、ここでは 解りやすくする為、省いてい ます。
  • 38.
    わんくま同盟 大阪勉強会 #60 レイヤ化アーキテクチャ レイヤ化自体は、フォルダ(名前空間)分けという 単純な方法でした。 しかし、MVC同様にどのオブジェクトはどのフォル ダに格納すべきか、よく考える必要があります。
  • 39.
    わんくま同盟 大阪勉強会 #60 少しだけ、 責務のレイヤ
  • 40.
    わんくま同盟 大阪勉強会 #60 責務のレイヤ •DDDSampleには直接記されていないのです が、DDDには、「責務のレイヤ」というレイヤ概 念があります。 •モデル層内部をより細かく分類して、不安定 箇所(仕様変更が多発する箇所)を切り離しま す。
  • 41.
    わんくま同盟 大阪勉強会 #60 責務のレイヤ 第16章 大規模な構造「責務のレイヤ」より
  • 42.
    わんくま同盟 大阪勉強会 #60 責務のレイヤ •責務のレイヤは、開発に非常に有効な手段と思いま す。 •しかし、責務のレイヤを実装するには、顧客(ドメイン エキスパート)の知識が必要となり、上流設計で行う 作業やスキルが必要となります。 ・業務知識の習得 ・業務の見える化 ・・・色々 やはり、一筋縄ではいかなそうです。
  • 43.
  • 44.
    わんくま同盟 大阪勉強会 #60 値オブジェクト •DDDでは、如何にモデルをシンプルに保つか が、大切な考えになります。 •オブジェクトに、責務以上の機能、余計なデー タを持たせない事に、注意を払います。
  • 45.
    わんくま同盟 大阪勉強会 #60 値オブジェクト •値オブジェクトは、“属性情報”だけを持ちます。 •属性情報とは、「色」や「大きさ」など、 対象の性質を表したものです。
  • 46.
    わんくま同盟 大阪勉強会 #60 値オブジェクト そして、値オブジェクトは次のルールが適応され ます。 •同一性(アイデンティティ)を持たない。 •不変(immutable)である。 (属性に変更が必要になった場合、属性を変更するのではなく、 新しい属性を持った値オブジェクトを作成する)
  • 47.
    わんくま同盟 大阪勉強会 #60 値オブジェクト DDDSampleのLeg(行程)をサンプルにして、実装を みてます。 Legは船の貨物の「積み込む地点」と、「荷下ろし地点」 を保持します。 ※ 単純化の為、DDDSampleから改変(省略)しています
  • 48.
    わんくま同盟 大阪勉強会 #60 値オブジェクト //値オブジェクト用インターフェース public interface IValueObject<T> { //属性が同じかチェック bool SameValueAs(T other); } 最初に、値オブジェクト用のインターフェースを用意。
  • 49.
    わんくま同盟 大阪勉強会 #60 値オブジェクト //Leg(行程)の値オブジェクト実装 public class Leg : IValueObject<Leg> { public Location LoadLocation { get; private set; } //荷積み地点 private Location UnloadLocation { get; private set; } //荷下ろし地点 public Leg(Location loadLocation, Location unloadLocation) { this.LoadLocation = loadLocation; this.UnloadLocation = unloadLocation; } public bool SameValueAs(Leg other) { if (this.LoadLocation != other.LoadLocation) return false; if (this.UnloadLocation != other.UnloadLocation) return false; return true; } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 50.
    わんくま同盟 大阪勉強会 #60 値オブジェクト •Leg(行程)サンプルの特徴は、属性として、 ・ LoadLocation(荷積み地点) ・ UnloadLocation(荷下ろし地点) を持ち、コンストラクタ以外に、属性を変更する 手段を持ちません。 •このLeg(行程)だけみると、値オブジェクトと 言っても、特別なことは無いように見えますね。
  • 51.
    わんくま同盟 大阪勉強会 #60 値オブジェクト その2
  • 52.
    わんくま同盟 大阪勉強会 #60 値オブジェクト •次は、Leg(行程)をリストとして保持する、Itinerary(運送スケジュール)オブジェクトを考えてみます。 •Itineraryは、Cargo(貨物)(後述するエンティティ)の Legをまとめたもので、Legリスト最初が出発点、最 後が到着点(目的地)となります。
  • 53.
    わんくま同盟 大阪勉強会 #60 値オブジェクト このItinerary(運送スケジュール)を値オブジェク トと考えた場合、不変性をどう考えればよいで しょうか? リストとして保持しているLeg(行程)に、1つでも 変更が生じた場合、Cargo(貨物)は、Itinerary(運送スケジュール)を破棄して、都度、新しいイ ンスタンスを用意しないといけないのでしょう か?
  • 54.
    わんくま同盟 大阪勉強会 #60 値オブジェクト DDD本の第16章『大規模な構造』の「責務のレイヤ」に、 次のように書かれています。 ソフトウェアにおけるこのレイヤは、計画作成と意思決 定に用いるツールをユーザに提供し、潜在的には一部 の意思決定を自動化できる (運送スケジュールが変更になった時、自動的に貨物 の経路を選択し直すなど) つまり、意思決定支援レイヤの責務として、変更対応 すればよいそうです。(うーん難しい!)
  • 55.
    わんくま同盟 大阪勉強会 #60 値オブジェクト 個人的解釈としては、 •運送スケジュール変更というのは、Cargo(貨物)自 体の責務ではない。 •スケジュール変更は、より上位の意思に寄るもので ある。(例:貨物運送担当者など) •その為、 RoutingService(経路選択サービス)を用 意し、スケジュール変更に伴う実装的負担を引き受 けることで、各オブジェクト構造をシンプルに保てる (余計な仕事をさせなくて済む)
  • 56.
    わんくま同盟 大阪勉強会 #60 値オブジェクト •まずは、Itinerary(運送スケジュール)の実装 をみてみましょう。
  • 57.
    わんくま同盟 大阪勉強会 #60 値オブジェクト // Itinerary(運送スケジュール)オブジェクト public class Itinerary : IValueObject<Itinerary> { private List<Leg> legs = null; public Itinerary(List<Leg> legs) { this.legs = legs; } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 58.
    わんくま同盟 大阪勉強会 #60 値オブジェクト Itinerary(運送スケジュール)は、単純にLeg(行 程)をリストで保持しているだけですね。 次は、Cargo(貨物)とRoutingService(経路選 択サービス)です。
  • 59.
    わんくま同盟 大阪勉強会 #60 値オブジェクト // Cargo(貨物) (後ページのエンティティ時にも記載) public class Cargo:IEntity { ~省略~ //運送スケジュール private Itinerary itinerary; //運送スケジュール変更 public void AssignToRoute(Itinerary itinerary) { this.itinerary = itinerary; } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 60.
    わんくま同盟 大阪勉強会 #60 値オブジェクト // Itinerary(運送スケジュール)を新しく作るサービスを用意 public class RoutingService { public List<Itinerary> fetchRoutesForSpecification(Cargo cargo) { //新しいltinerary(運送スケジュール)割り当て cargo.assignToRoute(toItinerary()); } //条件に従い、新しい運送スケジュール作成 private Itinerary toItinerary() { ~省略~ return new Itinerary(legs); } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 61.
    わんくま同盟 大阪勉強会 #60 値オブジェクト DDDSampleにおける実際のRoutingService(経路選択サービス)はもっと複雑です。 ただ、DDD的意図を読み取ると、経路変更の仕 事を、経路情報を持つCargo(貨物)に行わせる のではなく、Serviceとして外部に出したことによ り、Carg(貨物)がシンプルに保たれている事に、 意義があるのと考えています。
  • 62.
  • 63.
    わんくま同盟 大阪勉強会 #60 エンティティ •エンティティは値オブジェクトと異なり、同一性 (アイデンティティ)を持ちます。 •同一性は、モデルのライフサイクル期間中保 たれます。 •同一性は、エンティティをDB格納して、取り出 した後でも、保たれます。 エンティティ モデルのライフライン DB エンティティ 同じアイデンティティ
  • 64.
    わんくま同盟 大阪勉強会 #60 エンティティ •cargo(貨物)をサンプルに、エンティティの実 装を見てみます。 •cargo(貨物)は、TrackingId(追跡ID)をアイ デンティティとして、同一性を持ちます。 •TrackingId(追跡ID)は、作成時に割り当てら れた後、変更されることはありません。
  • 65.
    わんくま同盟 大阪勉強会 #60 エンティティ // エンティティ用インターフェース interface IEntity<T> { //同一エンティティかチェック bool sameIdentityAs(T other); } •まずはエンティティ用のインターフェース
  • 66.
    わんくま同盟 大阪勉強会 #60 エンティティ //cargo(貨物) public class Cargo:IEntity<Cargo> { private readonly TrackingId trackingId; public Cargo(TrackingId trackingId) { this.trackingId = trackingId; } public bool SameIdentityAs(Cargo other) { return other != null && trackingId.sameValueAs(other.trackingId); } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 67.
    わんくま同盟 大阪勉強会 #60 エンティティ •アイデンティティであるtrackingId(追跡ID)を readonlyにすることで、設定後の不意な変更 を防止しています。 •それ以外は特段特徴のない、普通のクラスで すね。
  • 68.
    わんくま同盟 大阪勉強会 #60 エンティティ •次に、そのアイデンティティとして使用されてい る TrackingId(追跡ID)の実装を見てみます。
  • 69.
    わんくま同盟 大阪勉強会 #60 エンティティ // TrackingId(追跡ID) public sealed class TrackingId : IValueObject<TrackingId> { private readonly String id; public TrackingId(String id) { this.id = id; } public override bool Equals(object o) { if (this == o) return true; if (o == null) return false; TrackingId other = (TrackingId)o; return SameValueAs(other); } public bool SameValueAs(TrackingId other) { return other != null && this.id.Equals(other.id); } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 70.
    わんくま同盟 大阪勉強会 #60 エンティティ •驚いた事に、 TrackingId(追跡ID)は値オブ ジェクトです。 •Cargo(貨物)は、エンティティですが、そのア イデンティティとして、値オブジェクトである TrackingId(追跡ID)を使用しています。
  • 71.
    わんくま同盟 大阪勉強会 #60 エンティティ これらの事から、何が値オブジェクトで、エンティ ティなのか、深く考える必要があることが伺えま す。 (エンティティのアイデンティティも、普通ならエンティティになると 普通思うと思います) 個人的には、容易にオブジェクトをエンティティと しないという、強い意志を感じました。
  • 72.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories
  • 73.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories •エンティティの実装例で見た通り、同一性の確 保は、プログラムの実装に依存します。 (例では、追跡IDのユニーク性確保など) •このように、新しくオブジェクトをnew(インスタ ンス化)したいときに、特定条件(今回は追跡 ID採番)を実行したい事は多々あります。
  • 74.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories •そこで、オブジェクトの生成、並びにDBへの格 納・取り出しなど、オブジェクト化するのに必要 な処理をまとめたのが、「Factories(ファクト リ)」と「Repositories(リポジトリ)」です。
  • 75.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories •「Factories」がオブジェクト生成時に使用。 •「Repositories」は、DB格納や取り出しなど、 オブジェクトを使いまわす時に使用します。
  • 76.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories •cargo(貨物)を格納するCargoRepositoryの 実装例は次のようになります。
  • 77.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories //貨物リポジトリ interface ICargoRepository { //指定、追跡IDに該当するcargo取得 Cargo find(TrackingId trackingId); //全cargoを取得 List<Cargo> findAll(); //DBに格納します void store(Cargo cargo); //DBなどのシーケンスを使い、ユニークなIDを発番させます。 TrackingId nextTrackingId(); }
  • 78.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories •ICargoRepositoryインターフェースを実装す ることで、O/Rマッパで実装するとDBに結びつ けたり、ファイル操作で実装すると、Textファイ ルとして保存させたり、することができます。 •次ページはDBで実装した時の例です。
  • 79.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories //貨物リポジトリ(DB) public class CargoRepositoryDb { private DAO dao=null; //指定、追跡IDに該当するcargo取得 public Cargo find(TrackingId tid) { dao.createQuery("from Cargo where trackingId = :tid"); //SQL dao.setParameter("tid", tid); return dao.result(); } //全cargoを取得 public List<Cargo> findAll() { dao.createQuery("from Cargo "); //SQL return dao.result(); } (続く) ※ 解りやすくする為に、DDDSampleから改変しています。
  • 80.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories (続き) // DBに格納します public void store(Cargo cargo){ dao.saveOrUpdate(cargo); dao.createSQLQuery("delete from Leg where cargoId =null").executeUpdate(); } // ユニークなIDを発番 public TrackingId nextTrackingId() { var randomId= dao.GetRoundomUID(); return new TrackingId(randomId); } } ※ 解りやすくする為に、DDDSampleから改変しています。
  • 81.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories Factoriesの実装例は載せておりませんが、 Repositoriesとほぼ同じような実装内容になりま す。 そうなってくると、FactoriesとRepositoriesをま とめても良さそうに思いますよね?
  • 82.
    わんくま同盟 大阪勉強会 #60 Factories と Repositories しかし、DDD本では、次の理由でFactoriesと Repositoriesの役割を分離させてます。 •Factoriesは、新しいオブジェクトを生成する責務。 •Repositoriesは、既存オブジェクトを再構成する責務。 •分離させることで、FactoriesをDB(永続)化する処 理から分離できる。
  • 83.
  • 84.
    わんくま同盟 大阪勉強会 #60 まとめ 簡単な実装例だけでしたが、 •レイヤ化アーキテクチャ •値オブジェクト •エンティティ •Repositories DDDの中核をなす、実装例を見て頂きました。
  • 85.
    わんくま同盟 大阪勉強会 #60 まとめ 他にもDDDSampleでは、 •集約(Aggregate) •ドメインイベント •Service •仕様(SPECIFICATION) などの実装例が紹介をされています。 (しかし、これらはDDDを知らないと、判りづらいかもしれませ ん)
  • 86.
    わんくま同盟 大阪勉強会 #60 書籍紹介 次に、DDD実装で参考になる書籍を簡単に紹介させて いただきたいと思います。
  • 87.
    わんくま同盟 大阪勉強会 #60 書籍紹介 ドメイン駆動 ■amazon http://www.amazon.co.jp/dp/4798116173 ■書籍紹介 C#を使った、ドメイン駆動設計をパターンを使って 実装していく実践本です。 まさに、C#er向けの一冊。 C#2.0と若干古いのですが、サンプルソースは参 考になります。 SQLServerと如何に連携させるか、 テスト駆動開発でいかに進めるかなど、 てんこ盛りな内容です。(少々詰め込み過ぎ?)
  • 88.
    わんくま同盟 大阪勉強会 #60 書籍紹介 Implementing Domain-Driven Design ■amazon http://amzn.com/0321834577 ■書籍紹介 英語本ですが、IDDDというキーワードでよく見かける、 DDD実践本です。 DDD本の後に出版された、如何にDDDを実践してい くかを主眼に書かれている本で、DDD本には収録さ れていなかったドメインイベントも記載されているよう です。 DDD本に劣らない分厚さを誇ります(汗。 私は当然、英語苦手なので未読です(汗汗 IDDDのワークショップを世界的に行うコミュニティがあ るようです。(http://idddworkshop.com/)
  • 89.
    わんくま同盟 大阪勉強会 #60 まとめ 最初にも書かさせて頂きましたが、DDDにお ける実装が占める役割は、ほんの一部です。 実装に至るまでの過程がもの凄く重要だと思い ます。 また、実装例として挙げたものより、状況に よって、より適切な実装方法は、数多くあると思 います。
  • 90.
    わんくま同盟 大阪勉強会 #60 まとめ 今回は、実装という方面からDDDを眺めてみ ましたが、DDDを知らなかった方に、少しでも興 味を持って頂けたのなら幸です。 DDDの実装については、私も勉強中です。 もし気になる点などありましたら、是非お声かけ 下さい。<(_ _)>ペコリ
  • 91.
    わんくま同盟 大阪勉強会 #60 まとめ 以上、ご清聴ありがとうございました。