113
第1週 ドメイン駆動設計の基本を理解する 201592日 増田亨(@masuda220) ギルドワークス株式会社 取締役 有限会社システム設計 代表 3週連続DDD 「ドメイン駆動設計の要点と実践ノウハウ」

3週連続DDDその1 ドメイン駆動設計の基本を理解する

  • Upload
    -

  • View
    12.221

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1週ドメイン駆動設計の基本を理解する

2015年9月2日 増田亨(@masuda220)

ギルドワークス株式会社 取締役

有限会社システム設計 代表

3週連続DDD 「ドメイン駆動設計の要点と実践ノウハウ」

Page 2: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1週のアジェンダ

• ドメイン駆動設計の「考え方」

「まえがき」を中心に

• ドメイン駆動設計の「3原則」

1章から3章

• ドメイン駆動設計の「基本スキル」

4章から7章

Page 3: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1週の内容を踏まえて

• 第2週 「深いモデルの探求」

–モデルと設計の継続的な探求の重要性

– ドメイン駆動設計的なリファクタリング

• 第3週 「戦略的に取り組む」

–より広い範囲で長期的に

–誰がやるのか

– どうやるのか

–いつやるのか

Page 4: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

はじめに

Page 5: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

そんな人のためにこの本の要点、考え方とやり方を実践経験をまじえて

そんな人のためにこの本の要点、考え方とやり方を実践経験をまじえて

・読み解くのが困難・実践でどう活用するか迷っている・やってみたがうまくいかない

Page 6: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

取り組み

•出会ったのは10年前

–よくわからなかった

•現場で取り組み始めて8年–7つの開発プロジェクト

–3つのコンサルティング

Page 7: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

やってみて

•手ごたえ/おもしろさ

•実践の難しさ

•たくさんの読み落とし

•たくさんの勘違い

•発見と学習と成長

Page 8: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」の考え方

Page 9: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」とは

厳しい現実の中で、ソフトウェア設計を習得しようと奮闘してきた技術者の物語。

不完全な状況の中で、抽象的な設計原則を、現実のソフトウェアに適用するための助言。

「日本語版への序文」 by エリック・エヴァンス

エヴァンスは、ソフトウェア開発の成功も失敗も味わってきた。この本は、エヴァンスが成功と失敗の両方から学んだ教訓を伝えている。

「序文」 by マーチン・ファウラー

Page 10: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

エヴァンスの取り組み

オブジェクト指向

エクストリームプログラミング

Page 11: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

エヴァンスの取り組み

この二つを組み合わせて、ソフトウェア開発に取り組んだ。その成功と失敗の経験から学んだことをまとめたものが「ドメイン駆動設計」。

オブジェクト指向

エクストリームプログラミング

Page 12: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」の想定読者

• 「オブジェクト指向」と「エクストリームプログラミング」に、ある程度の知識がある技術者

• 「オブジェクト指向」と「エクストリームプログラミング」の原則を、実際のアプリケーション開発に適用しようとして、理屈通りにいかないことを経験した技術者

「まえがき」から

Page 13: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向

エクストリームプログラミング

前提となる知識と経験

Page 14: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向

エクストリームプログラミング

前提となる知識と経験

私自身は、「ドメイン駆動設計」を初めて読んだ時は、DOA/手続き型/ウォータフォール系の技術者。この二つはある程度の知識はあったが未経験。読んでも良くわからないことがいっぱいあった。

「オブジェクト指向」と「エクストリームプログラミング」を勉強し、現場でいろいろ挑戦しているうちに「ドメイン駆動設計」の考え方が理解できるようになってきた。

Page 15: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

勉強になった本

Wabi Sabiを読み解く

オブジェクト指向 エクストリームプログラミング適応型のソフトウェア開発

Page 16: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向

エクストリームプログラミング

「適応型」のソフトウェア開発

Page 17: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向

エクストリームプログラミング

「適応型」のソフトウェア開発

2つに共通する考え方は、成長と変化を続ける「適応型」のソフトウェア開発

Page 18: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

変化に「適応」する技術

オブジェクト指向の「変更容易性」

エクストリームプログラミングの「変化適応性」

Page 19: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向の「変更容易性」

エクストリームプログラミングの「変化適応性」

• 「エクストリームプログラミング」は「オブジェクト指向」のコミュニティで生まれ育った

• オブジェクト指向の「変更容易性」が、「適応型」の開発スタイルをささえている

• 相互に補強しあう関係

変化に「適応」する技術

Page 20: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

エクストリームプログラミング「適応型」のソフトウェア開発

Page 21: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「適応型」のソフトウェア開発開発のスタイル

方法論の例

ソフトウェアの最終形(着地点)

開発サイクル

予測型ウォータフォール

事前に厳密に定義固定 分析/設計/製造

反復・漸進型

RUPそれなりに定義

反復ごとに精緻化

方向付/推敲/作成/移行

各フェーズで分析/設計/製造を、N回「反復」する

適応型XP

スクラムYAXP

ざっくりと定義日々更新

日、週、四季(人間の生活リズム)

Page 22: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

日々、変化し成長する• 毎日、方向付け/推敲/作成/移行を行う。– 午前は、「方向付け」と「推敲」のためにコードを書く– 午後は、がっつり「作成」する– 夕方、今日の成果を「配置」する– 毎日フィードバックを受け取る

• 最終の着地点と進行方向を確認しながら進む– 何か新しいことが起きていないか、毎日、見直す– 進む方向がずれていないか、毎日、見直す– 週で見直し、季節で見直す

• 「変化」を知覚したらチームで機敏に対応する– 方向の微調整かもしれない– おおきな方針転換かもしれない– 変えるべき時は大胆に、チーム一丸で

Page 23: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

YAXP(もうひとつのXP)

• 私がもっとも経験してきた開発スタイル

– ラフスケッチ一枚と口頭の依頼

–あいまいでふらつく要求/つかまらない担当者

–動く画面を見せる度に、追加要求と修正依頼

– 「なるはや」リリース

–人「いない」/予算「ない」

–なんでも自分(たち)でやるしかない

• 「ドメイン駆動設計」の良い実践の場

Page 24: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向の「変更容易性」

エクストリームプログラミングの「変化適応性」

• 「ドメイン駆動設計」の基礎となる設計と開発の考え方/やり方

• 相互に補強しあう関係

変化に「適応」する技術

Page 25: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向「変更容易性」の工夫

Page 26: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクト指向の「変更容易性」(どのパラダイムでも同じだけど)

• 抽象データ型/段階的な抽象化– プログラムを人間の発想に近づけると扱いやすい

• モジュラープログラミング– 独立性の高い部品に分けると扱いやすい

– 関連するデータと操作は、ひとつのプログラミング単位に

• メッセージング– 部品の組合せを柔軟に変更できると扱いやすい

– sender/receiver/routing

– オブジェクト指向言語でうまく実現できていない• Erlang, EIP:Enterprise Integration Patterns, マイクロ

サービス, …

Page 27: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

LocalDateクラス

DateOfBirthのインスタンス変数日付を汎用的に扱う手段Java APIのレイヤ

int yearshort monthshort day

LocalDateのインスタンス変数Java言語仕様のレイヤ

if( day > 31 ) …

DateOfBirthクラス

「誕生日」に用途を限定した独自定義クラス「ドメイン層」の一級市民(ドメインオブジェクト)人間の関心事

コンピュータの仕組み

抽象データ型/段階的な抽象化人間の発想に近づける

Boolean 今月が誕生月()Days 誕生日まであと何日()

plusDays()plusMonths()

Page 28: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

OO+XP=ドメイン駆動設計?

• 「ドメイン駆動設計」は「オブジェクト指向」と「エクストリームプログラミング」を組み合わせた開発の体験談

–エクストリームオブジェクト指向プログラミング

• 「ドメイン駆動設計」は、OO+XPの考え方とやり方の「強調」する点をずらしている

by エリック・エヴァンス

Page 29: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」が強調する点

• 「ドメイン」に焦点をあてる

• 「モデル」と「コード」の歩調を合わせながら、少しずつ「成長」させる

• 「言葉」を使って、チームで「モデル」と「設計」の「改良」を続ける

この三つを組み合わせてソフトウェアを開発した体験談が「ドメイン駆動設計」の特徴であり魅力。

Page 30: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」の理解の鍵

• 「ドメイン」に焦点を当てるとは、具体的にどういうことか

• 「モデル」と「コード」の歩調を合わせるとは、具体的にどういうことか

• 「言葉」を使って、チームで「モデル」と「設計」を改良するとは、具体的にどういうことか

• そのために「オブジェクト指向」と「エクストリームプログラミング」の考え方をどう実践するか

Page 31: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1部ドメインモデルを

機能させる

Page 32: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」の3原則

• 第1章 知識をかみ砕く

• 第2章 コミュニケーションと言葉の使用

• 第3章 モデルと実装を結びつける

Page 33: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン• ソフトウェアウェアを利用する人たちの「活動」と「関心事」–ソフトウェアの利用は、活動全体の一部

–関心事の焦点は、ビジネスや業務上の成果

• ドメインではないこと–ソフトウェアを作る活動

– コンピュータの仕組みや挙動

–画面仕様書/機能一覧/ユーザーストーリー/…

Page 34: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメインとソフトウェア

利用する人たちの活動と関心事

ソフトウェア

Page 35: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

活動の目的/背景

活動の文脈

ソフトウェア

利用する人たちの活動と関心事

Page 36: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメインのモデリング•利用する人たちの「活動」と「関心事」を要約する• 「活動」の要約–アクティビティ図/業務フロー図

• 「関心事」の要約–概念モデル図(クラス図/パッケージ図)

Page 37: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデル•膨大な知識を「要約」したシンプルでわかりやすい説明

•モデリングのスキル=「要約力」

–重要な要素を発見する力

–本質的でないものを削る力

–厳密に組み立てる力

ドメイン駆動設計を実践する勘所:「要約力」を磨く

Page 38: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメインモデル• ソフトウェアを利用する人たちの「活動」と

「関心事」の本質を簡潔に表したもの

• 表現

–チームでかわされる会話

–ラフスケッチ

–コード

–(文章や図)

Page 39: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメインモデル」を育てる• 最初は知識が貧弱な浅い「モデル」から

• 「ドメイン(利用する人たちの活動や関心事)」を学びながら、ドメインの知識を広げ「モデル」に反映する

• 重要な点を残し、些細な点を削りとりながら、「モデル」を深めていく

• 「モデル」と「全体」を並行して育てていく– さまざまな要素の入り組んだ関係を、「モデル」を

中核に整理していく

Page 40: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン駆動設計の基本テーマ

• 役に立つドメインモデルを「発見的に成長」させていく

• ドメインモデルの成長に歩調を合わせて、コード設計に「ドメインの知識を反映」していく

• モデルをコードで実装してみる実験から、「より役に立つドメインモデル」の手掛りを得る

• 「変化」と「成長」を続ける

Page 41: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1部 モデルを活用する

第2章言葉を使った意図の伝達

第1章(ドメインの)知識をかみ砕く

第3章モデルと実装を結びつける

モデルドメインモデル

ドメインの膨大な情報をかみ砕き、蒸留して、重要な関心事を鋭く説明する

選び抜かれたドメインの重要な関心事をコードで表現する

会話を繰り返してモデルを改善する(重要点を明確にする)

会話の中で重要な語彙を特定する

Page 42: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1章 知識をかみ砕く

• プリント基板(PCB)設計ツールの開発経験

• (経験から学んだ)効果的なモデリングの要素

• 知識のかみ砕き

• 継続的な学習

• 知識豊富な設計

• 深いモデル

Page 43: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「知識をかみ砕く」体験談

• 「知らない」「わからない」からの出発

• 知識の広げながら「モデル」を成長させる

• 「役に立つモデル」の発見– 「ドメイン」をうまく説明できて、かつ、コードで実装

できる「モデル」を探す

• 「深いモデル」の発見と利用–ソフトウェアを利用する人(PCB設計者)の、ものの

見方と重要な関心事への理解を深める

– ドメインを深く理解した知識をコードに反映する

Page 44: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

出発点

図というよりは、頭の中のイメージほとんど何もわかっていない

Page 45: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

知識の広がり

PCB設計者と会話をしながら聞き取れる語彙がちょっと増えてきた

Page 46: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ある程度理解できたら「モデル」が役に立つかコードで実験

だいぶ意思疎通ができるようになってきた段階のモデルPCB設計者の関心事をうまく説明し、かつ、設計として役に立ちそうか実験

Page 47: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

本質的な関心事にたどり着いた深いモデル

PCB設計者の本質的な関心事をうまく説明しつつ、ソフトウェアの基本構造としてそのまま使える「深いモデル」

Page 48: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

知識をかみ砕きながらモデルとコードを少しずつ成長させる

Page 49: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1章 まとめ• 知識のないところから出発する

• 語彙を増やす

• ただしい言い方(正しい意味)を覚える

• コードで表現してみる

• 本質的な関心事を探求する

• 継続的に学ぶ

• 知識をかみ砕いた成果が「ドメインモデル」– 利用する人たちの「活動」と「関心事」の本質を簡潔に

表現した言葉・図・コード

Page 50: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1部 モデルを活用する

第2章言葉を使った意図の伝達

第1章(ドメインの)知識をかみ砕く

第3章モデルと実装を結びつける

モデルドメインモデル

ドメインの膨大な情報をかみ砕き、蒸留して、重要な関心事を鋭く説明する

選び抜かれたドメインの重要な関心事をコードで表現する

会話を繰り返してモデルを改善する(重要点を明確にする)

会話の中で重要な語彙を特定する

Page 51: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第2章コミュニケーションと言語の使い方

• ユビキタス言語

–例:貨物輸送プログラム

• 声に出してモデリングする

• 1つのチームに1つの言語

• ドキュメントと図

• 説明のためのモデル

Page 52: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ユビキタス言語• いつでも、どこでも、誰とでも– 技術者だけで話あっている時に、「利用する人たちの

関心事」の言葉がでてくれば本物

• 一つ言葉を同じ意味で– 要求仕様や画面に現れる「用語」と、ソフトウェアを利

用する人たちが使う「言葉」の意味の食い違いに注意

• 一つの意味を同じ言葉で– 同じ意味に思える「別の言葉」に敏感に

• ユビキタス言語の中で、特に重要な語彙を選び抜いたものが「ドメインモデル」

Page 53: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

声に出してモデリングする• 良いモデルを見つける実践的な方法– 語尾まで明瞭に– しゃべりにくい– 耳障りが悪い

• 復唱ゲーム– 同じ言葉、同じ言い回しにならない

• 他の表現との不一致に敏感に– コード、図、コミットログ、チャット、メールなど書かれた言葉– 笑っちゃうくらう一致していない

• チームのドメインの理解が進み、要点がはっきりしてくると、よどみなく同じ言い回しがでてくるようになる

Page 54: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

一つのチームに一つの言語

• チーム内では一つ言葉を同じ意味で

– 要求仕様や画面に現れる「用語」と、ソフトウェアを利用する人たちが使う「言葉」の意味の食い違いに注意

• チーム内では、一つの意味は同じ言葉で

– 同じ意味に思える「別の言葉」に敏感に

• 第4部の「境界づけられたコンテキスト」や「継続的な統合」の基本原理

• エクストリームプログラミングでは、ドキュメントの代わりに「会話」をする

Page 55: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

言葉たいせつ• 「エクストリームプログラミング」では、言葉を

使った会話がドキュメントの代わり

–意図伝達の主要な手段

• 「言葉」は、そのままクラス/メソッド/パッケージの候補

• あらゆる場所で同じ言葉を

–会話/チャット/メール/コミットログ/ソースコード

Page 56: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

言葉たいせつ

•開発者が、利用者の「重要な関心事」をよどみなく語り始める安心感

•開発者が、技術用語しか使わない恐怖感

Page 57: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1部 モデルを活用する

第2章言葉を使った意図の伝達

第1章(ドメインの)知識をかみ砕く

第3章モデルと実装を結びつける

モデルドメインモデル

ドメインの膨大な情報をかみ砕き、蒸留して、重要な関心事を鋭く説明する

選び抜かれたドメインの重要な関心事をコードで表現する

会話を繰り返してモデルを改善する(重要点を明確にする)

会話の中で重要な語彙を特定する

Page 58: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第3章 モデルと実装を結びつける

• モデル駆動設計

• モデリングパラダイムとツールによるサポート

• 骨格を見せる:なぜモデルがユーザにとって重要なのか?

• 実践的モデラ

Page 59: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデル駆動設計ドメイン駆動設計が必要とするモデル

• 初期の分析を支援するだけでなく、設計において土台になるモデル

• 両方に役に立つモデルを探す

–簡単には見つからない

–最初からは見つからない

–少しずつ実験し、学習し、良いモデルに育てていく

–言葉による実験/コードによる実験

Page 60: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデリングパラダイムと使用言語

• オブジェクト指向は、モデリングと実装を一致させることが、考え方の基本にある– 分析クラス=実装クラス

– しかし、理屈通りにはなかなかうまくいかない

– そこで「ドメイン駆動設計」

• 手続き型プログラミングは、コンピュータを使ったデータ操作モデルになりがち– 基本データ型と、その操作命令だけのコード

– 人間の考え方に近づける段階的な抽象化の不足

• 「述語論理」と「論理型」プログラミングは一致している– 広くは採用されていない

Page 61: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

(ドメイン層の)骨格を見せるなぜモデルがユーザにとって重要か?

• 「モデル」が、利用者の「重要な関心事」を反映していれば、主要なクラスとその関係は、利用者にとって理解できる

• ソフトウェアとして表現された「モデル」から、利用者はソフトウェアの潜在的な可能性に触れることができる

• とんでもない勘違いを発見できる

• オブジェクトの構造を画面レイアウトや画面遷移的に説明すると、会話しやすい

Page 62: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

実践的モデラ

• コードを書かない人間が、利用者の活動や関心事を深く理解しても、良いソフトウェアは生まれない

• コードを書く人間が、ドメインの知識をかみ砕き、重要な関心事を正しく理解するのが、もっとも確実で、もっとも効果的なソフトウェア開発手法

Page 63: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第2部モデル駆動設計の

構成要素

Page 64: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第2部 モデル駆動設計の構成要素

• 第4章 ドメインを隔離する

• 第5章 ソフトウェアで表現されたモデル

• 第6章 ドメインオブジェクトのライフサイクル

• 第7章 言語を使用する:応用例

Page 65: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第2部 モデルと実装の一致

• モデルと実装の一致は非常に難しい

• 何をすべきか

– ドメインの隔離

–モデルをコードで表現する

– ドメインオブジェクトのライフサイクル

–モデル駆動設計のやり方(進め方)

Page 66: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第2部は基礎練習• ボールを蹴って止める基本の練習

• 相手に囲まれても確実にできる

• 90分走りぬいたあとでも確実できる

• ぬかるんだピッチでも確実にできる

• 第2部の構成要素をどんな状況でも、確実に使えることが、「第3部 深いモデル」、「第4部戦略的設計」を実践する土台になる。

Page 67: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第4章 ドメインを隔離する

• レイヤ化アーキテクチャ

• ドメイン層は「モデル」が息づく場所

• 利口なUI(アンチパターン)

• その他の隔離

Page 68: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

レイヤ化アーキテクチャ

Page 69: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメインの「隔離」

• ドメイン層を分離– 表面的な分離は簡単

• 現実– コントローラ層やページ記述にしみだした業務知識

• if(未承認なら) setDisable()

– 複雑なSQL文にまぎれこんだ業務知識• NOT EXIST xxx OR customer.type = 1

• 業務知識のまぎれこみに敏感になる– アンチパターンを覚える

• 継続的にリファクタリングする– 画面が動くと、あらたなビジネスルールが発見され、それをコント

ロールや画面で処理するアンチパターンが横行する

• データベースのフラグと区分はアンチパターンの宝庫

Page 70: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン層• 「モデル」を表現するのはドメイン層のコードの

一部

– 「重要な関心事」のコードのまわりに、その他の関心事のコードが集まってくる

• ドメイン層にドメインの知識を集め続ける

– コードが知識豊富になり、深いモデルの発見の可能性が広がる

–画面やSQLに書き加えられがちな、ビジネス知識を丹念に、継続的に、ドメイン層に移動する

Page 71: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン層にロジックを集める工夫

• 2ステップビュー

• 操作モデルとボタン表示

• 動的SQLの記述…

Page 72: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

2ステップビュー• ドメイン層とプレゼンテーション層の関係

• Step1:ドメインオブジェクトが論理構造を返す

–例えば、List<String>

• プレゼンテーション層のヘルパークラスが、論理構造を物理構造に変換する

–例えば、 <tr> </tr>

Page 73: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

操作モデルとボタン表示• 状態による操作の違い

• ActionList オブジェクトをプレゼンテーション層に渡す

• その情報を元にプレンゼンテーション層が、ボタンを出し入れする

Page 74: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

動的SQLの記述• ドメインオブジェクトに論理構造を持たせる

–動的な AND/OR 条件

–動的な ORDER BY 句

• データアクセス層のヘルパークラスが、ドメインオブジェクトが返す論理構造をSQLにマッピングする

Page 75: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第4章のまとめ

• ドメインを隔離する

• 形式的なコーディングルールや、フレームワークの導入だけでは、隔離できない

• プレゼンテーション層からドメインロジックを抽出してドメイン層に移動し続ける

• データソース層からドメインロジックを抽出してドメイン層に移動し続ける

• ちょっとした修正で、ドメインの知識がドメイン層以外に拡散する危険を察知する嗅覚を磨く

Page 76: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第5章

「モデル」をプログラムで表現する

• 関連

• エンティティ

• 値オブジェクト

• サービス

• モジュール

• モデリングパラダイム

Page 77: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第5章の問題意識

• モデルとコードの一致は難しい• 「モデル」は、人間の関心事の要約– 「自然言語」で表現する(意図を伝達する)

• プログラミング言語という人工言語で、どう、人間の関心事を表現するか?– 細かい点に気を配らないと、すぐにモデルと実装が離

れていく– モデル(重要な関心事)と実装が分離すると、ソフト

ウェアが的はずれなものになったり、変更がたいへんになる

– ソフトウェアの成長が止まる

Page 78: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデルをコードで表現する工夫

• スリムな「エンティティ」

• 部品の独立性を高める「値オブジェクト」

• 操作の自然な置き場所を見つける「サービス」

• 重要な関心事「ファーストクラスコレクション」

• ビジネスルールの表現手段「区分オブジェクト」

Page 79: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン駆動設計

Page 80: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

何が違うのか?

「関連」を考えなくて良い「集約(Aggregates)」を考えなくて良いデータベースとマッピングしやすい

「関心事」があいまい(ごった煮)

「関連」の設計と実装が必要「集約」の設計が必要データベースとのマッピングが複雑

「関心事」を発見してクラスに抽出

Page 81: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

成長を続ける「適応型」アプローチ

• ドメインを学びながら「関心事」を発見する

• 「関心事」をクラスに「抽出」しながら、モデルとコードの両方を育てる

• ドメインの「関心事」を、さらに深掘っていくとっかかり

– 住所がない場合?

– 複数の住所?

– 住所がわかる時/変わる時

Page 82: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン駆動設計のやり方

ボールを蹴って止める基礎技術

Page 83: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

値オブジェクト(Value Objects)

• 大きなクラスの「分割」ではなく、重要な「関心事」を発見し「抽出」する感覚

• メソッドを「知識豊か」にする手段– 引数の型/メソッドの返す値の型

× long を渡して String を返す◎ 「顧客ID」を渡して「住所」を返す

• 人間の関心事に近づける努力– int,String,LocalDateだけでは、ドメインの「関心

事」を具体的に表現できない– 「顧客」や「住所」など、関心事を表現する独自の「型」

を定義する• 抽象データ型/段階的な抽象化

Page 84: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

エンティティ(Entity)• 太りがち– インスタンス変数

– ロジック⇒概念が暗黙知になりがち

• とことんスリムにする– 「識別」という利用者の関心事に集中する• 一覧の表示順や検索項目

• 特に関心があることの発見

– 「内容を説明」する関心事は「値オブジェクト」にまかせる(別の議論にする)

Page 85: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン層のサービス• どの「エンティティ」や「値オブジェクト」に置くべ

きか迷うロジックがいろいろでてくてる

• そういう時は、そのロジックに名前を付けてクラスとして抽出してみる(実験)

– XxxPolicy

– XxxRule

– XxxProcedure…

Page 86: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン層のサービス 危険!

• 「手続き」にドメインの「関心事」が隠ぺいされがち– 深いモデルの探求の手掛りを見失う

• 同じ「ロジック」が複数サービスに重複しがち– 変更コストがあがる– モデルとコードの成長の障害になる

• 考え方とやり方– メソッドの引数と型は「ドメインオブジェクト」にする

• long や Stringを使わない

– 基本は多態(ルールの場合ごとの切り替え)の道具– それ以外の場合、リファクタリングの候補としておく

• より適切な置き場所を模索することで、良いモデルを探求

Page 87: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

その他の有用な構成要素

• ファーストクラスコレクション

• 区分オブジェクト

Page 88: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ファーストクラスコレクション

• コレクションをラップしたドメインオブジェクト• Products• PurchaseHistory

• 「一覧」や「履歴」を表現したオブジェクト– 一覧画面などに対応するドメインオブジェクト– 「一覧」に関する利用者の関心事のモデル

• SQL文の複雑な問合せでがんばる?– SQLの抽出条件は単純にして、微妙な抽出や問合せ

を、オブジェクトにやらせる、というのも選択肢– どちらが、ドメインの概念をうまく表現するか– 変更があった時に、どちらが楽で安全か

Page 89: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

区分オブジェクト

• 振る舞いを持った Enum• 区分ごとのロジックを別クラスに記述• Java言語使用に組み込まれた

Strategy/Stateパターン

説明とコード例は、googleで「場合わけの書き方あれこれ」で検索。または「ソフトウェアデザイン9月号」

場合ごとのルールを理解し表現する工夫

Page 90: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モジュール(Packages)

• 重要なモデリング要素–関連するドメインオブジェクト(の型)のグループ

–利用者の関心事の「境界」を表現する手段

–プログラミング単位

– テスト単位

• 「適応型」のアプローチの対象–新しい発見とともに、積極的にパッケージ名/

パッケージ構成を変更し育てていくこと

• 「第4部 戦略的設計」の主要ツール

Page 91: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデリングパラダイム

• このテーマが「第5章 ソフトウェアで表現されたモデル」に登場する意味– 「モデリングの考え方」と「実装の考え方」– 基本が同じであれば、モデルをコードで表現しやすい– 分析クラス=実装クラス

• 「モデル」と「実装」の歩調を合わせて育てていくこれがやりやすいパラダイムは?– モデリングの原則と実装の原則の歩調を合わせやす

い– モデリングの実践スタイルと実装の実践スタイルの歩

調を合わせやすい– モデルの変更と実装の変更の歩調を合わせやすい

Page 92: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

オブジェクトパラダイム

• エヴァンスが取り組んだこと(この本はその体験談)• オブジェクトの世界におけるオブジェクトではないもの– 述語論理(AND/OR/NOT/EXIST)– 複雑な数学計算– 関係データベース

• パラダイムを混在させる際にはモデル駆動設計に忠実であること– 実装パラダイムと対立しない(違いを正しく理解する)– ユビキタス言語を使って統合性を保つ– UMLにこだわらない– パラダイムの混在は懐疑的に(メリットよりデメリットを重く)

Page 93: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第5章のまとめ

• ソフトウエアで表現したモデル

• 「モデル」と「実装」の一致は難しい

• そのための基本スキルを体で覚える

• 丁寧に地道に続ける

• 第3部、第4部の土台

–ほんとうに役に立つのは深いモデルを見つけた時

–大きな効果がでるのは戦略的に取り組んだ時

Page 94: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第6章ドメインオブジェクトのライフサイクル

• 集約

• ファクトリ

• リポジトリ

Page 95: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第6章の問題意識と解決の工夫

• 複雑になりがちな箇所

– オブジェクトのライフサイクル管理

• 生成/格納・再構成/修正/削除

– オブジェクト間の整合性の管理

• 「モデル」をこの複雑さから守るために

– ドメインオブジェクトのネットワーク構造と「集約」

– オブジェクトの生成と「ファクトリ」

–必要なオブジェクトを簡単に入手する「リポジトリ」

Page 96: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「集約」

• ドメインオブジェクトのネットワーク構造

–利用者の「活動」や「関心事」の結びつきを反映するので、必然的に複雑になる

• 「集約」という単位を導入して、複雑なネットワークに「構造」を導入する(設計上の問題)

– 「ひとかたまり」として扱うべき境界を探す

–言語仕様上に表現手段がないのが難点

Page 97: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ファクトリ」

• オブジェクト(の集約)の生成– エンティティ(集約のルート)が自分で持つと、エンティ

ティ本来の関心事があいまいになる

– 「コード」が複雑になり「モデル」との対応があいまいになる

• 生成ロジックの置き場所– 「集約のルート」のファクトリメソッド

– 「集約の生成」に関わるオブジェクトのファクトリメソッド

– コンストラクタ

– 独立したファクトリクラス…

Page 98: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「リポジトリ」

• 必要なオブジェクトの集約を入手する

• あたかもすべてのドメインオブジェクトがメモリ上にあるように設計する–データベース設計やORマッピングをいったん忘れる

– interface 宣言で実装を分離する

• やりたいことをシンプルに宣言する• 注文 findBy(管理番号)

• 注文一覧 lookFor(検索条件)

• void register(注文)

Page 99: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第6章の補足(実践例)

• 注文Repository#prototype() – データベースのシーケンスを使った管理番号を持ったド

メインオブジェクトの生成

– 注文受付番号を持ったドメインオブジェクトを返す

– 入力画面に渡す

– デフォルト値の設定

• 「トランスファ」インタフェース– 「通知」を表現するモデル要素

– 「記録・参照」を表現した「リポジトリ」と似ている

– 実現手段は、データアクセス層で実装する

Page 100: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第7章 言語を使用する:応用例

• 4章、5章、6章の「構成要素」を組み合わせる実戦に近い練習

• 仮想的なチームが要求と実装の問題に対処しながら「モデル駆動設計」で開発をしていく例

• その過程で生じる「さまざまな問題」と「どう解決」されるかを見ていく

• 読み取るのはたいへんだが、発見と学びが多い章

Page 101: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第7章の構成(流れ)

1. 貨物輸送システムの概要2. ドメインを隔離する:アプリケーション層の導入3. エンティティと値オブジェクトを区別する4. 輸送ドメインの「関連」を設計する5. 「集約」の境界6. 「リポジトリ」を選択する7. シナリオをウォークスルーする8. オブジェクトの生成9. リファクタリングのために立ち止まる10.輸送モデルにおける「モジュール」11.新機能を導入する:配分チェック12.最後に

Page 102: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第7章はより実戦に近い練習

• 「モデル」と「実装」が育っていく過程とリズム

• 「モデル駆動」で設計するということ

– まず「アプリケーション層」を導入する

• 「ドメイン層」の議論を「機能」視点から隔離する

• 機能(処理)の詳細化からの設計ではない

–入出力項目(画面帳票)の定義は登場しない

• プレゼンテーション層無しのドメイン層の設計と実装

–データモデル/テーブル設計は登場しない

• データモデルから独立したドメイン層の設計と実装

Page 103: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

関連・集約・リポジトリ

• 第7章の議論のハイライト• 「関連」を設計する– 関連の方向の議論はドメインに対する洞察– 複雑な実装を避ける(成長容易性の確保)

• 「集約」の境界– ドメインオブジェクトの「かたまり」の定義– 概念(関心事)の境界の明確化– 開発単位

• 「リポジトリ」を選択する– 機能視点が登場するタイミング

• 検索/選択/登録 …

Page 104: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

3週連続 DDD第1週のまとめ

Page 105: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメイン駆動設計

• エクストリームオブジェクト指向プログラミング• 少しずつソフトウェアを成長させる「適応型」の

開発スタイル

オブジェクト指向

エクストリームプログラミング

Page 106: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」が強調する点

• 「ドメイン」に焦点をあてる

• 「モデル」と「コード」の歩調を合わせながら、少しずつ「成長」させる

• 「言葉」を使って、チームで「モデル」と「設計」の「改良」を続ける

この三つを組み合わせてソフトウェアを開発した体験談が「ドメイン駆動設計」の特徴であり魅力。

Page 107: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

「ドメイン駆動設計」の理解の鍵

• 「ドメイン」に焦点を当てるとは、具体的にどういうことか

• 「モデル」と「コード」の歩調を合わせるとは、具体的にどういうことか

• 「言葉」を使って、チームで「モデル」と「設計」を改良するとは、具体的にどういうことか

• そのために「オブジェクト指向」と「エクストリームプログラミング」の考え方をどう実践するか

Page 108: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ドメインモデルを活用する

第2章言葉を使った意図の伝達

第1章(ドメインの)知識をかみ砕く

第3章モデルと実装を結びつける

モデルドメインモデル

ドメインの膨大な情報をかみ砕き、蒸留して、重要な関心事を鋭く説明する

選び抜かれたドメインの重要な関心事をコードで表現する

会話を繰り返してモデルを改善する(重要点を明確にする)

会話の中で重要な語彙を特定する

Page 109: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

モデルと実装を一致させ続ける

• モデルと実装の一致は非常に難しい

• やるべきこと– ドメインを隔離し続ける

–モデルを的確にコードで表現する工夫を続ける

– ドメインオブジェクトの複雑化を防ぎ続ける

• 発見と学習と成長を続ける– ドメインの知識

–深いモデル

–実装に役立つモデル

Page 110: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

ボールを蹴って止める練習• スリムな「エンティティ」• 部品の独立性を高める「値オブジェクト」• 操作の自然な置き場所を見つける「サービス」

• 重要な関心事「ファーストクラスコレクション」• ビジネスルールの表現手段「区分オブジェクト」

• オブジェクトのネットワーク構造に切り込む「集約」• 生成を切り離して扱う「ファクトリ」• 全てはメモリ上にあるかのように「リポジトリ」

Page 111: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

第1週の内容を踏まえて

• 第2週 「深いモデルの探求」

–モデルと設計の継続的な探求の重要性

– ドメイン駆動設計的なリファクタリング

• 第3週 「戦略的に取り組む」

–より広い範囲で長期的に

–誰がやるのか

– どうやるのか

–いつやるのか

Page 112: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

最後に

Page 113: 3週連続DDDその1  ドメイン駆動設計の基本を理解する

• どんな状況でも改善できる

• どんなときでも「あなた」から改善を始められる

• どんなときでも「今日」から改善を始められる

エクストリームプログラミングの「はじめに」に記されたケント・ベックのメッセージ