Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
混沌からドメインモデルへ
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
philomagi
July 30, 2019
Programming
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
混沌からドメインモデルへ
カオスな実装のプロジェクトにおいて
カオス → Fat Model
Fat Model → ドメインモデル
と段階を経て、リファクタリングに取り組んだ試み
philomagi
July 30, 2019
More Decks by philomagi
See All by philomagi
SkillとAgentを一元管理する / Centrally manage Skills and Agents
tooppoo
0
48
初めてのGitHub Actions / GitHub Actions at First
tooppoo
0
180
OSS開発を通じて考える、AI時代開発のこれから / The Future of Software Development in the AI Era
tooppoo
0
92
Bunではじめる standalone CLI / start standalone-cli with bun
tooppoo
0
33
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
220
Multi-Agent並列開発を 安全に回すための技術 / Technology for Safely Multi-Agent Parallel Development
tooppoo
0
310
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
3
1.9k
なぜ定義は問題解決に直結するのか/why-definitions-are-linked-to-problem-solving-with-tdd
tooppoo
0
110
ドメイン駆動設計のホーリズム的側面 / domain-driven-design and holism
tooppoo
0
240
Other Decks in Programming
See All in Programming
AIと壁打ちしながら進めるコスト管理
fufuhu
2
2k
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
230
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
6
3.2k
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
130
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
230
ソフトウェアラスタライザ
fadis
1
800
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
490
XHTMLが残したもの
yosuke_furukawa
PRO
2
590
GKE で Pod の見方を変えたら、スケールアウト時の挙動を真に捉えられた話
stkk
0
110
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
1.6k
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
640
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
480
Featured
See All Featured
Designing for humans not robots
tammielis
254
26k
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
230
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
BBQ
matthewcrist
89
10k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
890
Why Our Code Smells
bkeepers
PRO
340
58k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
320
The Cult of Friendly URLs
andyhume
79
7k
Transcript
混沌からドメインモデルへ 段階的リファクタリングの試み 2019/07/30@設計会議
発表者 topo / @Philomagi • 主にフロントエンド主体のWEB系エンジニア • ScalaとTypescriptとRubyが好き ◦ Rubyは最近、公私共に若干疎遠
• PHPは中々縁が切れない悪友 ◦ 最近は、そう腐すほどでもないかなと思い始めてる
概要 • 設計が存在しないプロジェクト • 既存コードが色々とアレ • まずはFat Modelで手元を見えるように • 道具を揃えてからドメインモデルへ
1. 混沌
混沌とした状況 • コードの重複 • モデル貧血症 • 詳細に依存 • UtilityじゃないUtil
カプセル化?なにそれ美味しいの? $props = Hash::extract($item->get('props'), "{n}[name=/^{$propName}[.]/]" ※Viewのコード(イメージ)
カプセル化?なにそれ美味しいの? return [ 'stock.enough' => $item->get('stock.amount') >= 10, // 中略
'status.hoge' => count($item->extract("props.{n}[name={$hogeStatusName}]")) >= 1, ]; ※Utilのコード(イメージ)
View Controller Util Model Hash
View Controller Util Model Hash • Fat View(Smart UI) •
Fat Controller • Fat Util • 貧血モデル
2. 混沌からFat Modelへ
Why Fat Model? • 次々に飛んでくる回収要望・追加機能 ◦ モデル分析のための時間も体力も確保し難い • 取り敢えず、直近触るコードだけでも見通しよくした い
Fat Modelへ • ロジックをDTOへ集約 • 詳細へのアクセスをメソッド経由に • 必要に応じてValueObjectも追加 • Utilは基本的に削除
◦ 入り組んでるものは、可能ならModel経由の利用に変更
Before / After $props = Hash::extract($item->get('props'), "{n}[name=/^{$propName}[.]/]" $sizes = $item->getSizesWhere($sizeName);
Before / After return [ 'stock.enough' => $item->get('stock.amount') >= 10,
// 中略 'status.hoge' => count($item->extract("props.{n}[name={$hogeStatus}]")) >= 1, ]; return [ 'stock.enough' => $item>stock()->isEnough(), // 中略 'status.hoge' => $item>isHoge(), ];
View Controller Util Model Hash
View Controller Util Model Hash • Fat Model
3. Fat Model から Domain Model へ
• モデルを描いて共有 ◦ 仕様を握っている人と認識を揃える • 語彙を統一 ◦ DDDにおけるユビキタス言語 • 部分的に、使えるところから導入開始
◦ 一気の置き換えは狙わない Domain Model の導入
Domain Object の実装 • 統一した語彙を、クラス名/メソッド名で使用する • データとDomain Objectの分離 ◦ DTO
→ Domain Objectのマッピング層を用意 ◦ Factory、Repository • Modelに集約したロジックをDomain Objectに移動 ◦ ModelはただのDTOになり、ロジックはDomain Objectが持つ • パッケージでコンテクストを表現 ◦ パッケージ内のオブジェクトは、ひたすらそのコンテクストに特化
View Controller DomainObject DomainObject View Controller DomainObject View Controller Mapping
Infrastructure Model(DTO) Mapping Mapping
振り返って プラマイ両方有ったが、マイナスが強い • 「何が用意してあるのか」「何が用意されてないのか」を確認 できる • 「とりあえず読めなくはない」には持っていける • Modelに強く依存した実装になってしまう ◦
DTOがプロジェクト全体を支配してしまうため
評価 • 今回はとにかくスタート地点が真っ暗闇だった • まずは手元に何が有り、何が無いのかを把握したかった • 今回のケースでは、一定程度の妥当性は有ったかなと感じて いる • 決して、Bestなプロセスでは無いと思う
◦ 緊急回避的 ◦ 経由せずに済むなら経由しない方が良い
反省点 • 「設計しない」ための言い訳としてFat Model化し た感も有る • 設計を後回しにしたことで首が締まったことも多い • 複雑なシステムこそ、時間が無くともきちんと設計 すべき
ご清聴ありがとうございました