devlove beautiful development - 第一幕 陽の巻

Post on 24-Jan-2015

4.572 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

【DDD陽の巻 Pt.II】

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

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

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

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

自己紹介

• 都元ダイスケ (@daisuke_m)

• Jiemamy / java-ja

• Apache Mahout

• Java / OO / DDD

• 元薬屋

works

• @IT — Jiemamy

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

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

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

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

僕と地豆とDDD

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

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

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

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

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

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

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

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

Agenda

• DDD overview

• Isolating the Domain

• Model

• LifeCycle

§0 DDD overview

• DDDはパターン言語

• GoFデザインパターン

• PoEAA

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

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

ユビキタス言語

• ユーザ

• 会員

• 利用者

• (管理者)

言葉の混乱

顧客と共有

トンデモ?

ドメインとは

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

• 問題領域

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

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

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

非ドメインコード

• UIを描画するコード

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Model Driven Design (モデル駆動)

• 全てはモデルなり

Model or Not• LibHTTP

• Search

• FacebookLogin

• Translation

• FoobarLogic

• User

• File

• String

• StringBuilder

• YearMonth

実体 モデル? 非モデル

§1 ドメインを分離せよ

• ドメイン層

• 非ドメイン層

• インフラ層

• アプリ・UI層

LAYERED ARCHITECTURE

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

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

• 依存の方向

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

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

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

• どっちか選べ

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

THE SMART UI"ANTI-PATTERN"

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

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

ここを綺麗に分離すべき

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

• ENTITY (E)

• VALUE OBJECT (VO)

• SERVICE

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

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

• 相互依存問題

• Table knows Columns / Column knows Table

• Emp knows Dept / Dept knows Emps

相互依存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);

解決アイデア

• Declaration & Reference

• Repository後述!

ENTITY (E)

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

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

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

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

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

• Serialize / Deserialize するとclone…

実体

31歳の俺(File / DB)

32歳の俺(On Memory)

ENTITYの例• Table

• Column

• ForeignKey

• Employee

• Department

• Order

• Customer

ENTITYの特徴

• 同一性・連続性を持つ

• 主たる責務は「特定」

• IDを持つ

• equalsとhashCodeはIDに基づく

ピザ屋• 顧客はENTITY

• IDは電話番号

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

• 引越し

• 番号の共有

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

tableFoo.addColumn(col);

tableBar.addColumn(col);

// something

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

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

思考停止の誘惑

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

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

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

VALUE OBJECT (VO)

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

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

• man.getName(): String の比較

• equalsとhashCodeは全propertyに基づく

VALUE OBJECTの例• Integer

• BigDecimal

• String

• Color

• Date / TimePoint

• Status (OPEN / PROGRESS / CLOSED)

VALUE OBJ.の特徴

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

• 主たる責務は「説明」

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

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

SERVICE

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

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

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

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

SERVICEの特徴

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

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

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

思考停止の誘惑

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

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

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

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

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

MODULE

• 略(ぉぃ

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

Javaのpackage

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

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

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

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

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

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

§3 LifeCycleを制御せよ

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

• new ~ GC

• INSERT ~ DELETE

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

§3 LifeCycleを制御せよ

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

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

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

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

AGGREGATE

• 略(ぉぉぉぃ

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

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

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

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

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

FACTORY

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

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

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

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

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

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

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

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

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

REPOSITORY

• 参照を入手する方法

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

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

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

• Repositoryで検索する

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

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

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

• On Memory Collection

• Database

Repos.はCollection

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

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

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

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

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

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

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

まとめMODULES

top related