devlove beautiful development - 第一幕 陽の巻

60
DDD陽の巻 Pt.IIBuilding Blocks ~DDDと愉快なモデル達~ 都元ダイスケ トライクレオ() - tricreo.jp / Jiemamy Project - jiemamy.org 2011.04.09 @ オラクル青山センター 注意:本セッションは都元のトンデモが含まれているかもしれません

Upload: daisuke-miyamoto

Post on 24-Jan-2015

4.572 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: DevLOVE Beautiful Development - 第一幕 陽の巻

【DDD陽の巻 Pt.II】

Building Blocks~DDDと愉快なモデル達~

都元ダイスケトライクレオ(株) - tricreo.jp / Jiemamy Project - jiemamy.org

2011.04.09 @ オラクル青山センター

注意:本セッションは都元のトンデモが含まれているかもしれません

Page 2: DevLOVE Beautiful Development - 第一幕 陽の巻

自己紹介

• 都元ダイスケ (@daisuke_m)

• Jiemamy / java-ja

• Apache Mahout

• Java / OO / DDD

• 元薬屋

Page 3: DevLOVE Beautiful Development - 第一幕 陽の巻

works

• @IT — Jiemamy

• 日経ソフトウエア• Javaで始めるプログラミング

• Javaで始めるオブジェクト指向

• Java: The Good Parts (レビュー)

• エリックエヴァンスのDDD (レビュー)

Page 4: DevLOVE Beautiful Development - 第一幕 陽の巻

僕と地豆とDDD

• Jiemamy Project (地豆)• 悩• しげるんば• 初洋書 DDD

• 上司• Jiemamy version 0.3 リリース• baseunits library (timeandmoney)

http://d.hatena.ne.jp/daisuke-m/20110407/1302156870

Page 5: DevLOVE Beautiful Development - 第一幕 陽の巻

Jiemamyでの経験• この際、ER図エディタだと思っていいです

• Eclipse上で動く (UI関連の制約)

• DBモデリング, SQL (ドメインルール)

• テーブル・関連・キー・SQL…

• XML I/O, DDD (技術インフラ)

Page 6: DevLOVE Beautiful Development - 第一幕 陽の巻

Agenda

• DDD overview

• Isolating the Domain

• Model

• LifeCycle

Page 7: DevLOVE Beautiful Development - 第一幕 陽の巻

§0 DDD overview

• DDDはパターン言語

• GoFデザインパターン

• PoEAA

Page 8: DevLOVE Beautiful Development - 第一幕 陽の巻

DDD PATTERNS• STRATEGY

• COMPOSITE

• BOUNDED CONTEXT

• CONTINUOUS INTEGRATION

• CONTEXT MAP

• SHARED KERNEL

• CUSTOMER/SUPPLIER DEVELOPMENT TEAMS

• CONFORMIST

• ANTICORRUPTION LAYER

• SEPARATE WAYS

• OPEN HOST SERVICE

• PUBLISHED LANGUAGE

• INTEGRATION

• OPEN HOST SERVICE

• CORE DOMAIN

• GENERIC SUBDOMAINS

• DOMAIN VISION STATEMENT

• HIGHLIGHTED CORE

• COHESIVE MECHANISMS

• SUGGESTED CORE

• ABSTRACT CORE

• EVOLVING ORDER

• SYSTEM METAPHOR

• RESPONSIVILITY LAYERS

• KNOWLEDGE LEVEL

• PLUGGABLE COMPONENT FRAMEWORK

Page 9: DevLOVE Beautiful Development - 第一幕 陽の巻

DDD PATTERNS• UBIQUITOUS LANGUAGE

• MODEL-DRIVEN DESIGN

• HANDS-ON MODELERS

• LAYERED ARCHITECTURE

• THE SMART UI "ANTI-PATTERN"

• ENTITIES

• VALUE OBJECTS

• SERVICES

• MODULES

• AGGREGATES

• FACTRIES

• REPOSITORIES

• SPECIFICATION

• INTENTION-REVEALING INTERFACES

• SIDE-EFFECT-FREE FUNCTION

• ASSERTIONS

• CONCEPTUAL CONTOURS

• STANDALONE CLASSES

• CLOSURE OF OPERATIONS

Page 10: DevLOVE Beautiful Development - 第一幕 陽の巻

ユビキタス言語

• ユーザ

• 会員

• 利用者

• (管理者)

言葉の混乱

顧客と共有

トンデモ?

Page 11: DevLOVE Beautiful Development - 第一幕 陽の巻

ドメインとは

• そもそもドメインって何?

• 問題領域

• ソフトウェアがそもそも解決しようとする関心事

Page 12: DevLOVE Beautiful Development - 第一幕 陽の巻

Domain or Not家計簿アプリの場合

• 科目毎の毎月の合計額を集計できる• 家計簿入力ボタンを押すと入力画面に遷移する• 家計簿の編集履歴をHISTORYテーブルに保存する• 残額は翌月に繰り越せる• 毎月の締め日を設定できる• 科目毎の毎月の予算を設定できる• 出納額として数値以外を入力したらエラー

Page 13: DevLOVE Beautiful Development - 第一幕 陽の巻

非ドメインコード

• UIを描画するコード

• DBから必要情報を読み出すコード

• ユーザ入力を解釈・検証するコード

• 操作結果をDBにコミットするコード

Page 14: DevLOVE Beautiful Development - 第一幕 陽の巻

ドメインコード• 科目などの選択肢をルールに従って選別するコード

• 家計簿のエントリをエントリとして束ねるコード

• 月ごとの合計額を計算するコード• 毎月の予実を比較して評価するコード

Page 15: DevLOVE Beautiful Development - 第一幕 陽の巻

主作用・副作用• 意図した作用 → 主作用• 意図しない作用 → 副作用• レスタミン®

•  効果:アレルギー• 副作用:眠気• ドリエル®

•  効果:睡眠改善• 副作用:(鼻水が止まりますw)

Page 16: DevLOVE Beautiful Development - 第一幕 陽の巻

オブジェクト指向との関係

• 本書はオブジェクト指向の本ではない

• 急進的な設計を提案するものでもない

• 従来の考え方の上で、焦点を当てるポイントを動かしただけだ

Page 17: DevLOVE Beautiful Development - 第一幕 陽の巻

• オブジェクト指向を前提としていない

• が、結局はオブジェクト指向

• 全てはオブジェクトなり

• Model Driven Design (モデル駆動)

• 全てはモデルなり

Page 18: DevLOVE Beautiful Development - 第一幕 陽の巻

Model or Not• LibHTTP

• Search

• FacebookLogin

• Translation

• FoobarLogic

• User

• File

• String

• StringBuilder

• YearMonth

実体 モデル? 非モデル

Page 19: DevLOVE Beautiful Development - 第一幕 陽の巻

§1 ドメインを分離せよ

• ドメイン層

• 非ドメイン層

• インフラ層

• アプリ・UI層

Page 20: DevLOVE Beautiful Development - 第一幕 陽の巻

LAYERED ARCHITECTURE

• ではドメインと非ドメインを分けよう

• 右図は例; ドメインさえきちんと分離されていれば構わない

• 依存の方向

Page 21: DevLOVE Beautiful Development - 第一幕 陽の巻

Jiemamy

jiemamy-core

jiemamy-commonsapache commons

jiemamy eclipse plugin

maven-jiemamy-plugin

jiemamy-diagram

jiemamy-sql

DiagramEditorTableView

DbObjectEditPart

ExecuteMojo

JmDiagramJmNode / JmConnection

SqlStatementToken JmTable / JmView

JmColumnJmForeignKeyConstraint

SqlExecutor / UUIDProviderwoodstoxXMLInputFactory

XMLValidationSchema

UIApplication

Domain

Infrastructure

Page 22: DevLOVE Beautiful Development - 第一幕 陽の巻

• DDD本内で記述される唯一のアンチパ

• モデル駆動とは両立しない

• どっちか選べ

• 作るものがlightなら、MDD要らないよ

THE SMART UI"ANTI-PATTERN"

Page 23: DevLOVE Beautiful Development - 第一幕 陽の巻

オブジェクト指向のコードでは、UIやDB関連等の非ドメインコードがビジネスオブジェクト(ドメイン)に記述されがちである

User#save(); → DBアクセスtoString() ! "<span>...</span>"

ここを綺麗に分離すべき

Page 24: DevLOVE Beautiful Development - 第一幕 陽の巻

§2 モデルを表現せよ• ここがメインディッシュ!• 関連を限定せよ• ドメインモデルオブジェクトは3種類

• ENTITY (E)

• VALUE OBJECT (VO)

• SERVICE

Page 25: DevLOVE Beautiful Development - 第一幕 陽の巻

関連を限定せよ• 便利なだけの依存はなくす

• 本質的な依存に限定する

• 相互依存問題

• Table knows Columns / Column knows Table

• Emp knows Dept / Dept knows Emps

Page 26: DevLOVE Beautiful Development - 第一幕 陽の巻

相互依存class Emp { String name; Dept dept;}

class Dept { String name; List<Emp> members;}

Dept tech = new Dept("技術部");Emp kato = new Emp("加藤");kato.setDept(tech);tech.addMember(kato);

Page 27: DevLOVE Beautiful Development - 第一幕 陽の巻

解決アイデア

• Declaration & Reference

• Repository後述!

Page 28: DevLOVE Beautiful Development - 第一幕 陽の巻

ENTITY (E)

• 本質的に、属性によってではなく、連続性と同一性によって定義されるオブジェクト

• 識別する責務• 都元ダイスケ vs 宮本大輔

• 宮本大輔(SE) vs 宮本大輔(野球)

Page 29: DevLOVE Beautiful Development - 第一幕 陽の巻
Page 30: DevLOVE Beautiful Development - 第一幕 陽の巻

同一性• 31歳の時の借金は32歳でも有効か?

• 同日、同口座、同額の入金は区別

• Serialize / Deserialize するとclone…

実体

31歳の俺(File / DB)

32歳の俺(On Memory)

Page 31: DevLOVE Beautiful Development - 第一幕 陽の巻

ENTITYの例• Table

• Column

• ForeignKey

• Employee

• Department

• Order

• Customer

Page 32: DevLOVE Beautiful Development - 第一幕 陽の巻

ENTITYの特徴

• 同一性・連続性を持つ

• 主たる責務は「特定」

• IDを持つ

• equalsとhashCodeはIDに基づく

Page 33: DevLOVE Beautiful Development - 第一幕 陽の巻

ピザ屋• 顧客はENTITY

• IDは電話番号

• ここには割り切りがあります

• 引越し

• 番号の共有

Page 34: DevLOVE Beautiful Development - 第一幕 陽の巻

Eは共有できないColumn col = ...; // ← ENTITY

tableFoo.addColumn(col);

tableBar.addColumn(col);

// something

tableFoo.getColumn(...).setName("AAA");

tableBarのカラム名も同時に変わる

Page 35: DevLOVE Beautiful Development - 第一幕 陽の巻

思考停止の誘惑

• 全てのモデルにIDを持たせよう

• 地豆でやったことあります (v0.2)

• オブジェクトの管理コストが高騰してエラい目に遭いました

Page 36: DevLOVE Beautiful Development - 第一幕 陽の巻

VALUE OBJECT (VO)

• ある特徴や属性を記述するが、同一性の概念を持たないオブジェクト

• 特徴を説明する責務• new String("foo") vs new String("foo")

• man.getName(): String の比較

• equalsとhashCodeは全propertyに基づく

Page 37: DevLOVE Beautiful Development - 第一幕 陽の巻

VALUE OBJECTの例• Integer

• BigDecimal

• String

• Color

• Date / TimePoint

• Status (OPEN / PROGRESS / CLOSED)

Page 38: DevLOVE Beautiful Development - 第一幕 陽の巻

VALUE OBJ.の特徴

• 同一性・連続性を持たない

• 主たる責務は「説明」

• Immutableであることが望ましい

• インスタンスの共有ができる Flyweight

Page 39: DevLOVE Beautiful Development - 第一幕 陽の巻

SERVICE

• 基本的に、操作は特定のEやVOなどのモデルに属する

• 特定のEやVOに属させてしまうと不自然な場合は、Serviceを作ると安定する

• 複数のEやVOに横断的な処理

• 外部システムとの通信を伴う処理

Page 40: DevLOVE Beautiful Development - 第一幕 陽の巻

SERVICEの特徴

• ステートレス• 操作名はユビキタス言語(UL)

• 入出力はドメインオブジェクト

• が、望ましい。 → 思考停止禁止

Page 41: DevLOVE Beautiful Development - 第一幕 陽の巻

思考停止の誘惑

• 振る舞いはに既存の E / VO に載せたい• 振る舞いを載せるための新たな(非モデル)E / VO 風オブジェクトを作りたい• 早々に E / VO に載せるのを諦めたい• 諦めたのが Transaction Script

• モデルはタダの値の入れ物に墜ちる

Page 42: DevLOVE Beautiful Development - 第一幕 陽の巻

サービス色々• Infrastructure Service (技術的)• E-mail 送信• 業務知識が一切混ざらないはず• Application Service

• 銀行取引履歴のExcel export• ファイル形式にドメイン的意味はない• Domain Service

• 銀行振り込み• 個人的には命名が悪いと思っちょる

Page 43: DevLOVE Beautiful Development - 第一幕 陽の巻

MODULE

• 略(ぉぃ

• 嘘です。軽くいきますね。

Page 44: DevLOVE Beautiful Development - 第一幕 陽の巻

Javaのpackage

• 多くは漠然と使われている

• これらのクラスは1つのモジュールである、という「大枠の構造」を示す

• ドメイン知識が明らかになるにつれてリファクタリングが必要

Page 45: DevLOVE Beautiful Development - 第一幕 陽の巻

MVCの罠• com.example.foobar• model• FooModel• BarModel• view• FooView• BarView• controller• FooController• BarController

ULじゃねえよ

ULじゃねえよ

ULじゃねえよ

•com.example.foobar• foo• FooModel• FooView• FooController• bar• BarModel• BarView• BarController

Page 46: DevLOVE Beautiful Development - 第一幕 陽の巻

MVCの罠• com.example.foobar• model• FooModel• BarModel• view• FooView• BarView• controller• FooController• BarController

ULじゃねえよ

ULじゃねえよ

ULじゃねえよ

•com.example.foobar• foo• FooModel• FooView• FooController• bar• BarModel• BarView• BarController

スーパークラスで分類すんな

Page 47: DevLOVE Beautiful Development - 第一幕 陽の巻

§3 LifeCycleを制御せよ

• 全てのObjectにはライフサイクルがある

• new ~ GC

• INSERT ~ DELETE

• 実体にもライフサイクルがある

Page 48: DevLOVE Beautiful Development - 第一幕 陽の巻

§3 LifeCycleを制御せよ

Page 49: DevLOVE Beautiful Development - 第一幕 陽の巻

Eのライフサイクル• 実体のLifeCycleはObjectのLifeCycleを超える

• システムがダウンしたらUserは消えるが、ユーザの存在がこの世からは消えない

(消えるかもしれないけどw)

• JVM上に一時的に存在しない時もある

Page 50: DevLOVE Beautiful Development - 第一幕 陽の巻

AGGREGATE

• 略(ぉぉぉぃ

• いや、まぁ、さらっといきますね…

Page 51: DevLOVE Beautiful Development - 第一幕 陽の巻

集約• 複雑性を避ける仕組み• Table が集約ルート

• Columnが集約されている要素Entity

• Columnの同一性はTable内部で識別

• 外部のObjがColumnの参照を保持してはならない→必ずTableを介してアクセス

Page 52: DevLOVE Beautiful Development - 第一幕 陽の巻

FACTORY

• コンストラクタ• 車が車の作り方を知ってる?• インスタンスの作り方の知識はnewの時しか要らない• 複雑なObject生成をそのObject自身が持つとカオスが訪れる可能性• ならばインスタンスを作る知識だけファクトリに分離するといいかも?

Page 53: DevLOVE Beautiful Development - 第一幕 陽の巻

ファクトリ• 通常Obj.の生成構築はドメイン上無意味

• ObjectとしてのLifeCycleの開始を司る

• ただし思考停止するなよー

• 単純ならばObject自身が持っていた方がシンプルなのは真実です

Page 54: DevLOVE Beautiful Development - 第一幕 陽の巻

Obj.の自己防御義務• 不変条件の維持義務

• Obj.は自身を不正な状態に遷移させる操作を拒否しなければならない

• 不完全なObj.は生成できてはならない

• 当然FactoryによるObj.生成も同様

Page 55: DevLOVE Beautiful Development - 第一幕 陽の巻

REPOSITORY

• 参照を入手する方法

• オブジェクトを生成する

• 他オブジェクトから関連を辿る

• 顧客は過去の全ての注文を保持するのか?

• Repositoryで検索する

Page 56: DevLOVE Beautiful Development - 第一幕 陽の巻

リポジトリ• EntityとしてのLifeCycleを司る

• LC開始済みのEntityを取得する手段

• 実際にnewしているかは隠蔽

• On Memory Collection

• Database

Page 57: DevLOVE Beautiful Development - 第一幕 陽の巻

Repos.はCollection

• ドメインオブジェクトはDBに直接クエリを投げてはならない

• Repositoryは(裏で何をしていようと)Collectionのように振る舞うべき

• store / delete / find (resolve) ... を提供

Page 58: DevLOVE Beautiful Development - 第一幕 陽の巻

Declaration & ReferenceCREATE TABLE FOOBAR (

FOO INTEGER,

BAR VARCHAR(32),

PRIMARY KEY (FOO),

FOREIGN KEY (BAR)

REFERECE BAZ (QUX)

);

CREATE TABLE FOOBAR (

FOO INTEGER,

BAR VARCHAR(32),

PRIMARY KEY (FOO),

FOREIGN KEY (BAR)

REFERECE BAZ (QUX)

);

CREATE TABLE FOOBAR (

FOO INTEGER,

BAR VARCHAR(32),

PRIMARY KEY (FOO),

FOREIGN KEY (BAR)

REFERECE BAZ (QUX)

);

Decl. = Entity

Ref. = VO(ID)

Table has-a Column(s) and ...PrimaryKey has-a ColumnReference

Page 59: DevLOVE Beautiful Development - 第一幕 陽の巻

まとめ• すべてはオブジェクト / モデルなり• ドメイン層のモデルは

ENTITY / VO / SERVICE として作る• ライフサイクルは

FACTORY / REPOSITRY で制御• DDDは考え続ける為のパターンです

Page 60: DevLOVE Beautiful Development - 第一幕 陽の巻

まとめMODULES