SlideShare a Scribd company logo
1 of 33
Download to read offline
Python における
ドメイン駆動設計(戦術面)の
勘どころ
2017-09-09 @ PyCon JP 2017
林 淳哉
自己紹介
● 林 淳哉 (@loose_agilist)
● GROOVE X でロボット開発
● 「実践ドメイン駆動設計」 Reviewer
● Qiita に DDD の記事書いてます
今日おはなしすること
● ドメイン駆動設計とは
● ドメイン駆動設計の悩みどころ
● Todo List を例にしたドメイン駆動設計の実践
○ https://github.com/ledmonster/ddd-python-inject
$ git clone
https://github.com/ledmonster/ddd-python-inject
$ cd todolist
$ python setup.py develop
$ ./bin/todo --help
ドメイン駆動設計とは何か
● Eric Evans が提唱した設計手法
● モデリング技術 や オブジェクト指向設計 を抽象化し、
問題領域の抽出から、アーキテクチャ設計、モデリング、
実装に至る全工程を 一貫性のある体系 として整理したも
の
おすすめ書籍
エリック・エヴァンスのドメイン駆動設計 (2011)
“Domain Driven Design” Eric Evans (2003)
DDD 信者の聖書。その難解さから「鈍器」と呼ばれる。抽象度が高く、分厚いので
読み通すの大変だが、何回読んでも発見がある。ここで整理されている概念は、 10
年以上経った今も色褪せない。 
実践ドメイン駆動設計 (2015)
“Implementing Domain Driven Design” Vaughn
Vernon (2011)
Evans 本の中身は本質を突いているが、その実践は容易でない。本書は、 Evans
本以降の10年間に発表された新しい開発技法を取り込みながら、 DDD の考え方
を実践に移すにはどうすれば良いかを記述した指南書。
※ 読むのに挫折しても、鈍器としてなら使えます
※
※ 翻訳レビューに参加しました。
ドメイン駆動設計を構成する要素
● 「戦略」的側面
○ 将棋でいう「定跡」
○ プロダクト全体を俯瞰するための考え方
● 「戦術」的側面
○ 将棋でいう「手筋」
○ 個々の実装のための考え方
● ユビキタス言語
○ プロダクト全体で統一された言葉
を使おう
● コアドメイン、サブドメイン、汎用
ドメイン
○ 問題領域を整理しよう
● 境界付けられたコンテキスト
○ 実装するシステムを整理しよう
● コンテキストマップ
○ システム間の関係を整理しよう
ドメイン駆動設計の
「戦略」的側面
ドメイン駆動設計の
「戦術」的側面
● アーキテクチャ
○ MVC, MVVM などの実装パターン
● ドメインモデル
○ エンティティ
■ 識別子を持つもの
○ 値オブジェクト
■ 値に型を与えたもの
○ サービス
■ 振舞いだけを提供するもの
○ リポジトリ
■ 永続化の仕組み
○ ファクトリ
■ オブジェクトを生成する仕組み
○ 集約
■ 不変条件を管理する単位
○ ドメインイベント
■ エンティティの変化を表現したイベント
● アプリケーション
○ コンテキスト全体の調整役
ヘキサゴナルアーキテクチャとは
● 依存性逆転の原則(DIP)を用いて、
ドメインモデルから外部システム(DB・UIなど)への
依存を排除したアーキテクチャ手法
● 古い方法
○ 商品管理のロジックが Redis に依存する
● ヘキサゴナルアーキテクチャ
○ 商品管理ロジックにストレージのインタフェースを定義し、
インタフェースに合うように MySQL アダプタを実装する
CQRSとは
● Command and Query Responsibility Segration
○ コマンドクエリ責務分離
○ Greg Young (2010)
● クエリ(副作用なし)とコマンド(副作用あり)を分離する考え方
○ 一貫性
■ 「コマンド」では整合性が求められる
■ 「クエリ」ではあまり気にしない
○ ストレージ
■ 「コマンド」では正規化してデータを保存したい
■ 「クエリ」では非正規化して効率的にデータを取得したい
○ スケーラビリティ
■ 「コマンド」は負荷が大きくなりづらい
■ 「クエリ」は負荷が大きくなりやすい
● ドメイン駆動設計は、コマンドと相性が良い
いざ実践しようとすると悩む・・・
悩みどころ
● 参考になる Python 実装がない
● ソースコードが肥大化しがち
● リポジトリの実装が複雑になってしまう
● 値オブジェクトの不変性を表現できない
● ヘキサゴナルアーキテクチャの使い方が分からない
● CQRS を適用したいけど、分からない
● 名前の付け方で悩む
● OR Mapper を使って良いのか悩む
というわけで
サンプルを作りました
$ git clone
https://github.com/ledmonster/ddd-python-inject
$ cd todolist
$ python setup.py develop
$ ./bin/todo add --name 発表資料を作る
#1: 発表資料を作る
$ ./bin/todo list
[ ] #1: 発表資料を作る
$ ./bin/done 1
[x] #1: 発表資料を作る
Task
TaskRepository
TaskStatus
User
UserService
TaskRedisR
epository
TaskMemory
Repository
Redis
Memory
Simple
UserService
app/cliConsole (app/http)
Web
未実
装
Domain Model
Adapters
Read Model
TaskQuery
TaskDto
Todo List
考え方
● 名前を大切にする
● テストを書く
● ヘキサゴナルアーキテクチャを活用する
● DI コンテナを活用する
● DBアクセスライブラリを活用する
● CQRS で読み出し専用ロジックを分離する
● 値オブジェクトを活用する
名前を大切にしよう
● 違和感を感じたら直す
○ 始めから適切な名前がつけられるとは限らない
○ 良い名前を思いついたら、チームで合意して、直す
○ 適切な名前をつけると、モデルの中身も整理される
● 長過ぎる名前を避ける
○ 経験上、長すぎる名前は活用されづらい
○ 時には略称を活用する
■ 例: decision making → dm
● 曖昧な言葉は、ドメインに対する理解不足のサイ
ン
テストを書こう
● メンタルモデルとソースコードを合わせることが大切
● テストがないと、違和感のあるコードを修正できず、
ドメイン駆動設計の効果が半減する
ヘキサゴナルアーキテクチャを活用しよう
● ドメインモデルを中心に置くことで、
テストのしやすい、柔軟なシステムが構築できる
● アプリケーションは、「アダプタ」+「設定」
○ HTTP / CLI アダプタ
○ 各種設定
Task
TaskRepositor
y
TaskStatu
s
User
UserService
TaskRedis
Repository
TaskMemor
yRepository
Redis
Memor
y
Simple
UserService
app/cliConsole (app/http)
Web
未実装
Domain Model
Adapters
DI コンテナを活用しよう
DI コンテナを使わない場合
● コンストラクタで依存性を注入
● 依存関係が増えると悪夢
DI コンテナを活用しよう
DI コンテナ(inject)を利用
● https://pypi.python.org/pypi/Inject/3.1.1
● DI コンテナで依存関係を一元管理
DI コンテナを活用しよう
DI コンテナ(inject)を利用
● https://pypi.python.org/pypi/Inject/3.1.1
● DI コンテナで依存関係を一元管理
● コンストラクタが汚染されない
DB のアクセスライブラリを活用しよう
● リポジトリの実装に OR マッパーなどの
ライブラリを使っても構わない
● Todo List での実装
○ adapter/redis 以下にスキーマ定義
○ adapter/repo/redis でスキーマを利用
DB のアクセスライブラリを活用しよう
https://github.com/groove-x/gxredis
todolist.adapter.redis.task todolist.adapter.repo.task.redis
CQRS で読み出し専用ロジックを分離しよう
失敗談
● 検索要件が増えると、リポジトリが肥大化
● リポジトリの入出力はエンティティや値オブジェクトのため、
○ 入出力のオーバーヘッドが大きい
○ 書式の最適化がしづらい
○ ドメインモデルと整合性を取りながらメンテナンスするのが大変
○ DB 固有の最適化がしづらい
CQRS で読み出し専用ロジックを分離しよう
改善案
● 読み出し専用の処理は read_model として分離する
○ リポジトリをシンプルに保てる
○ 読み出し処理を最適化できる
値オブジェクトを活用しよう
● エンティティが増えがち
● コンテキスト内で属性を変更しないなら、
値オブジェクトにできる
● 例
○ 外部のコンテキストで管理している
オブジェクトを参照する場合
Task
TaskRepository
TaskStatus
User
UserService
TaskRedisR
epository
TaskMemory
Repository
Redis
Memory
Simple
UserService
app/cliConsole (app/http)
Web
未実
装
Domain Model
Adapters
Read Model
TaskQuery
TaskDto
Todo List
まとめ
● Python でドメイン駆動設計を実践しました
○ 名前の付け方を大切にしよう
○ テストを書こう
○ ヘキサゴナルアーキテクチャを使って
ドメインモデルと外部依存の実装を分離しよう
○ DIコンテナ(inject)で依存性を管理しよう
○ DB のアクセスライブラリを活用しよう
○ CQRS で読み出し専用ロジックを分離しよう
○ 値オブジェクトを活用しよう
Python におけるドメイン駆動設計(戦術面)の勘どころ

More Related Content

What's hot

日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについて
kumake
 

What's hot (20)

ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
ドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDDドメイン駆動設計 の 実践 Part3 DDD
ドメイン駆動設計 の 実践 Part3 DDD
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
 
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門
 
ドメイン駆動設計 分析しながら設計する
ドメイン駆動設計 分析しながら設計するドメイン駆動設計 分析しながら設計する
ドメイン駆動設計 分析しながら設計する
 
日本語テストメソッドについて
日本語テストメソッドについて日本語テストメソッドについて
日本語テストメソッドについて
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方ドメイン駆動設計の正しい歩き方
ドメイン駆動設計の正しい歩き方
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し
 
「速」を落とさないコードレビュー
「速」を落とさないコードレビュー「速」を落とさないコードレビュー
「速」を落とさないコードレビュー
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
 
シリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかシリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのか
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計
 

Viewers also liked

東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
Nagi Teramo
 

Viewers also liked (7)

Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?
 
Sappo ro#6資料2 ー完全版ー
Sappo ro#6資料2 ー完全版ーSappo ro#6資料2 ー完全版ー
Sappo ro#6資料2 ー完全版ー
 
R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装R6パッケージの紹介―機能と実装
R6パッケージの紹介―機能と実装
 
Prophet入門【理論編】Facebookの時系列予測ツール
Prophet入門【理論編】Facebookの時系列予測ツールProphet入門【理論編】Facebookの時系列予測ツール
Prophet入門【理論編】Facebookの時系列予測ツール
 
Prophet入門【R編】Facebookの時系列予測ツール
Prophet入門【R編】Facebookの時系列予測ツールProphet入門【R編】Facebookの時系列予測ツール
Prophet入門【R編】Facebookの時系列予測ツール
 
Prophet入門【Python編】Facebookの時系列予測ツール
Prophet入門【Python編】Facebookの時系列予測ツールProphet入門【Python編】Facebookの時系列予測ツール
Prophet入門【Python編】Facebookの時系列予測ツール
 
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
東京R非公式おじさんが教える本当に気持ちいいパッケージ作成法
 

Similar to Python におけるドメイン駆動設計(戦術面)の勘どころ

ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
Hiroh Satoh
 

Similar to Python におけるドメイン駆動設計(戦術面)の勘どころ (20)

はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
 
hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計hooks riverpod + state notifier + freezed でのドメイン駆動設計
hooks riverpod + state notifier + freezed でのドメイン駆動設計
 
ゼロからのプログラミングRails講座 Codeanywhere版
ゼロからのプログラミングRails講座 Codeanywhere版ゼロからのプログラミングRails講座 Codeanywhere版
ゼロからのプログラミングRails講座 Codeanywhere版
 
今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版今さら聞けない人のためのGit超入門 GitLab 13対応版
今さら聞けない人のためのGit超入門 GitLab 13対応版
 
The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#
 
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
 
ドメイン駆動設計とは何か 【入門編】
ドメイン駆動設計とは何か 【入門編】ドメイン駆動設計とは何か 【入門編】
ドメイン駆動設計とは何か 【入門編】
 
マイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorpマイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorp
 
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
ぼくのかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく - YAPC Asia 2011
 
コードの自動修正によって実現する、機能開発を止めないフレームワーク移行
コードの自動修正によって実現する、機能開発を止めないフレームワーク移行コードの自動修正によって実現する、機能開発を止めないフレームワーク移行
コードの自動修正によって実現する、機能開発を止めないフレームワーク移行
 
今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版今さら聞けない人のためのGit超入門 GitLab 14対応版
今さら聞けない人のためのGit超入門 GitLab 14対応版
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
うちの開発におけるXD利用法
うちの開発におけるXD利用法うちの開発におけるXD利用法
うちの開発におけるXD利用法
 
ソフトウェア工学2023 13 ドキュメンテーション
ソフトウェア工学2023 13 ドキュメンテーションソフトウェア工学2023 13 ドキュメンテーション
ソフトウェア工学2023 13 ドキュメンテーション
 
夏サミ2013 Hadoopを使わない独自の分散処理環境の構築とその運用
夏サミ2013 Hadoopを使わない独自の分散処理環境の構築とその運用夏サミ2013 Hadoopを使わない独自の分散処理環境の構築とその運用
夏サミ2013 Hadoopを使わない独自の分散処理環境の構築とその運用
 
コンテナーによるIT基盤変革 - IT infrastructure transformation -
コンテナーによるIT基盤変革 - IT infrastructure transformation -コンテナーによるIT基盤変革 - IT infrastructure transformation -
コンテナーによるIT基盤変革 - IT infrastructure transformation -
 
Developers Summit 2023 9-D-1「もう悩まされない開発環境、プロジェクトで統一した環境をいつでもどこでも」
Developers Summit 2023 9-D-1「もう悩まされない開発環境、プロジェクトで統一した環境をいつでもどこでも」Developers Summit 2023 9-D-1「もう悩まされない開発環境、プロジェクトで統一した環境をいつでもどこでも」
Developers Summit 2023 9-D-1「もう悩まされない開発環境、プロジェクトで統一した環境をいつでもどこでも」
 
Rancherを活用して開発効率を上げる
Rancherを活用して開発効率を上げるRancherを活用して開発効率を上げる
Rancherを活用して開発効率を上げる
 
今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21今さら聞けない人のためのGit超入門 2019/11/21
今さら聞けない人のためのGit超入門 2019/11/21
 
今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門今さら聞けない人のためのgit超入門
今さら聞けない人のためのgit超入門
 

More from Junya Hayashi

断言して間違えると信頼度が低下するというベイズの話
断言して間違えると信頼度が低下するというベイズの話断言して間違えると信頼度が低下するというベイズの話
断言して間違えると信頼度が低下するというベイズの話
Junya Hayashi
 
DynamoDB Before and After GSI
DynamoDB Before and After GSIDynamoDB Before and After GSI
DynamoDB Before and After GSI
Junya Hayashi
 

More from Junya Hayashi (11)

断言して間違えると信頼度が低下するというベイズの話
断言して間違えると信頼度が低下するというベイズの話断言して間違えると信頼度が低下するというベイズの話
断言して間違えると信頼度が低下するというベイズの話
 
ヒキガエルは地震を予知するのか
ヒキガエルは地震を予知するのかヒキガエルは地震を予知するのか
ヒキガエルは地震を予知するのか
 
量から質への転化の法則
量から質への転化の法則量から質への転化の法則
量から質への転化の法則
 
DynamoDB Before and After GSI
DynamoDB Before and After GSIDynamoDB Before and After GSI
DynamoDB Before and After GSI
 
IT業界の記事に見られる「中日ドラゴンズの論理」の落とし穴
IT業界の記事に見られる「中日ドラゴンズの論理」の落とし穴IT業界の記事に見られる「中日ドラゴンズの論理」の落とし穴
IT業界の記事に見られる「中日ドラゴンズの論理」の落とし穴
 
U分布と宇宙
U分布と宇宙U分布と宇宙
U分布と宇宙
 
Pyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみたPyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみた
 
カタンの流れを検証してみた
カタンの流れを検証してみたカタンの流れを検証してみた
カタンの流れを検証してみた
 
サンクトペテルブルクのパラドックス
サンクトペテルブルクのパラドックスサンクトペテルブルクのパラドックス
サンクトペテルブルクのパラドックス
 
サイコロを100万回振ってみた
サイコロを100万回振ってみたサイコロを100万回振ってみた
サイコロを100万回振ってみた
 
Cross2013_GREE
Cross2013_GREECross2013_GREE
Cross2013_GREE
 

Python におけるドメイン駆動設計(戦術面)の勘どころ