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
hatsu
September 17, 2026
Programming
440
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
RailsTokyo#6
https://railstokyo.connpass.com/event/400709/
hatsu
September 17, 2026
More Decks by hatsu
See All by hatsu
active って名前で誤魔化すな / DON'T JUST CALL IT "ACTIVE"
hatsu38
0
120
Prism.parseで 300本以上あるエンドポイントに 接続できる権限の一覧表を作ってみた
hatsu38
1
220
MySQL初心者が311個のカラムにNot NULL制約を追加していってALTER TABLEについて学んだ話
hatsu38
2
470
introduction_scriptor_gem.pdf
hatsu38
1
210
約9000個の自動テストの 時間を50分->10分に短縮 Flakyテストを1%以下に抑えた話
hatsu38
25
21k
Just a Rails Patch Update
hatsu38
2
1k
Dive into MaintenanceTasks
hatsu38
1
240
GitHub Actions is Fun
hatsu38
1
240
Other Decks in Programming
See All in Programming
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
120
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
250
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
160
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
130
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
350
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
iOSDC2026登壇資料.pdf
riofujimon
0
210
CodeRabbitの効果検証と過ごしてみた3ヶ月
armondando
0
130
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
900
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
540
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
360
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
4.9k
Featured
See All Featured
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Site-Speed That Sticks
csswizardry
13
1.5k
How STYLIGHT went responsive
nonsquared
100
6.3k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
860
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
We Are The Robots
honzajavorek
0
380
Music & Morning Musume
bryan
48
7.4k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
710
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
290
Transcript
モデルのリファクタリングが難しいと思ったら、 そもそも複雑だったのはビジネス仕様だった ? 課題内在性負荷と言う前に要件と意図を聞いてちゃんとモデリングしよう RailsTokyo #6 ‧ 2026/09/17 ‧ @hatsu_38
02 · SELF INTRODUCTION ⾃⼰紹介 2019.4~ フリーランス 2024.6 SHE.inc 2024.09
Kaigi on Rails で CIの話をした 2026.09 RailsTokyo#6 で話します @hatsu_38 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 02 / 32
03 · AGENDA 話すこと 1. 複雑さの紹介 と 課題内在性負荷‧課題外在性負荷 2. 弊社の「会員システム」の簡単な紹介
3. 「休会」の設計はイケてなかったのか? 4. モデルの⽬的と安定依存の原則(SDP) ※ リファクタリング というより “リ”アーキテクト や “リ”モデリング って表現が正しい RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 03 / 32
04 · DOUBLE BILLING コトの発端 - ⼆重課⾦ • • •
不要な注⽂申し込み(=⼆重課⾦)が いくつかの状態の組み合わせで発 ⽣してしまっていた 管理画⾯から注⽂を⾏い、休会中 に退会申請を出し、その後休会復 帰予定より前に休会復帰した場合 に発⽣する 要は「退会」や「休会」で、サブ スクで次に注⽂するべき⽇と商品 の判定が難しくなっていた →リアーキテクトしよう! RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 04 / 32
05 · PAUSE COMPLEXITY 特に「休会」ってやつが複雑だった! 休会ができる条件の図 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?)
05 / 32
06 · PAUSE ELIGIBILITY 休会可能条件 - 簡略化図 in FAQ •
• FAQ では、休会の資格要件だけ 抜き出したフローチャートを載 せている 通常休会 のご利⽤はできません https://docs.channel.io/shelikes/ja/articles/休会はできる-95144692 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 06 / 32
07 · SPECIAL PAUSE 休会可能条件 - 簡略化図 in FAQ •
• FAQ では、休会の資格要件だけ 抜き出したフローチャートを載 せている 通常休会 のご利⽤はできません https://docs.channel.io/shelikes/ja/articles/休会はできる-95144692 • 通常休会ができなくても、 特別休会 できる可能性もある https://docs.channel.io/shelikes/ja/articles/妊娠/出産、家族の介護、⼊院 で受講の継続が難しい場合は休会できる?-95144692 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 07 / 32
不吉な匂い 【不可思議な名前】 明快なコードにするために最も重要なのは、適切な 名前付けです。そのため開発者は、関数、モジュー ル変数、クラスなどの名前について、⾏っているこ とや利⽤⽅法がはっきりと伝わるようにと、懸命に 考えます 参考: リファクタリング 既存のコードを安全に改善する
第2版 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 08 / 32
None
10 · COGNITIVE LOAD 複雑さは仕⽅ないのか? - 認知的負荷の種類 課題内在性負荷 課題外在性負荷 その問題⾃体がどのくらい複雑か
その問題の妨げとなる外部要因 8² + 6² = ?² a² + b² = c² ? 8 ? a a=b+2 b=3*2 6 b この問題は、他に解き⽅がなく、これらの⼿ 順を簡略することができないため、この問題 を解く際の負荷は問題に内在しているのです 問題を解く⽅法そのものは難しくなっていな い。しかし aとbを関連付け、bと6を関連付ける 課題外在性の作業に脳を働かせる必要がある 参考: プログラマー脳 優れたプログラマーになるための認知科学に基づくアプローチ RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 10 / 32
11 · COGNITIVE LOAD 複雑さは仕⽅ないのか? - 認知的負荷の種類 課題内在性負荷 その問題⾃体がどのくらい複雑か この問題は、他に解き⽅がなく、これらの⼿順
を簡略することができないため、この問題を解 く際の負荷は問題に内在しているのです 課題外在性負荷 その問題の妨げとなる外部要因 問題を解く⽅法そのものは難しくなっていな い。が、activeの意味はバラバラなので、ワー キングメモリに⼊れておかないけない 11 / 32 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?)
この複雑な休会条件は本当に 「他に解き⽅がなく、これらの⼿順を簡略することができない」 状態だったのか?
13 · AGENDA 話すこと 1. 複雑さの紹介 と 課題内在性負荷‧課題外在性負荷 2. 弊社の「会員システム」の簡単な紹介
3. 「休会」の複雑さと、なぜ複雑になったのか 4. モデルの⽬的と安定依存の原則(SDP) ※ リファクタリング というより “リ”アーキテクト や “リ”モデリング って表現が正しい RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 13 / 32
14 · MEMBERSHIP SYSTEM 会員証の仕組み 太郎さん SHElikes 会員証 在籍 2023
年 4 ⽉から サブスク Nヶ⽉ごとにスタンプを N個買い続ける仕組み(N=1,6,12) 次回 9⽉ XX プラン購⼊予定 4月 5月 6月 7月 8月 9月 10月 11月 12月 スタンプ スタンプが押された⽉は利⽤可能⽉ 退会 月毎にスタンプ購入 = 1ヶ月単位 のサブスク 太郎さん サブスクによる購⼊予定 カードを返す SHElikes 会員証 在籍 2023 年 4 ⽉から 次回 9⽉ XX プラン購⼊予定 4月 5月 6月 7月 8月 9月 6ヶ月まとめてスタンプ購入 = 6ヶ月単位 のサブスク 10月 11月 12月 14 / 32
15 · PAUSE REQUIREMENTS 休会機能を作りたい!(当時の会話) PdM サブスクによる注⽂を⼀定期間⽌める機能作りたいの。 その期間は⼊会中だけど休会中ってことにしたい! Eng サブスクを⽌めるんですね!6
か⽉契約の⼈が途中で休会したい場合はないですか? PdM それはルールに違反しているのでないです! Eng サブスクを⽌める期間(=休会)を設定できるようにして、その間注⽂を⽌めるようにしますね! 15 / 32 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?)
16 · PAUSE TIMING 休会はスタンプが終わるタイミングから開始可能 太郎さん 5月 6月 Nヶ⽉ごとにスタンプを N個買い続ける仕組み(N=1,6,12)
3ヶ月休会 = サブスク停止期間 次回 9⽉ XX プラン購⼊予定 4月 サブスク SHElikes 会員証 在籍 2023 年 4 ⽉から 7月 × 8月 × 9月 11月 10月 12月 スタンプ スタンプが押された⽉は利⽤可能⽉ × 退会 カードを返す 1ヶ月単位 のサブスク サブスクによる購⼊予定 休会 サブスクを⽌める。スタンプの満期で休会可能 太郎さん 在籍 2023 年 4 ⽉から 次回 9⽉ XX プラン購⼊予定 4月 5月 6月 6ヶ月単位 のサブスク 途中に休会はしない 🙅 3ヶ月休会 = サブスク停止期間 7月 10月 11月 × × × 8月 9月 12月 SHElikes 会員証 1月 2月 3月 16 / 32
17 · SUBSCRIPTION PAUSE サブスクを停⽌するテーブル作成 Newテーブル サブスク停⽌期間を持つ RailsTokyo #6 ‧
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 17 / 32
18 · SPECIAL PAUSE 休会機能、やっぱりスタンプの途中でも休会したい! しばらくして... PdM 6 か⽉の契約期間中だけど、体調が悪くて休会したいって⼈が現れていて。特別ルールで 許可してあげて!
Eng サブスクを⽌める期間の設定はできるけど、途中の休会は想定してなかったよ... 既存の「休会」は、サブスクを⽌めるを前提に実装したので、サブス クが関係ない休会は実現できなかった。 そして実装時間を省いた昔の我々は...オペレーションでカバー! → 「特別休会」というオペレーション誕⽣💥 18 / 32
19 · PAUSE LIMITATIONS サブスク停⽌はできるけど、スタンプの途中の休会はできない... 太郎さん SHElikes 会員証 在籍 2023
年 4 ⽉から サブスク Nヶ⽉ごとにスタンプを N個買い続ける仕組み(N=1,6,12) 次回 9⽉ XX プラン購⼊予定 4月 5月 6月 3ヶ月休会 7月 × 8月 × 9月 10月 11月 12月 スタンプ スタンプが押された⽉は利⽤可能⽉ × 退会 カードを返す 月毎にスタンプ購入 = 1ヶ月単位 のサブスク サブスクによる購⼊予定 休会 サブスクを⽌める。スタンプの満期で休会可能 太郎さん 次回 9⽉ XX プラン購⼊予定 4月 SHElikes 会員証 在籍 2023 年 4 ⽉から 5月 6月 途中に休会したい、、、 7月 8月 9月 6ヶ月まとめてスタンプ購入 = 6ヶ月単位 のサブスク 3ヶ月特別休会 = 無料でスタンプを付与 10月 1月 月 1月 2月 3月 19 / 32
20 · AGENDA 話すこと 1. 複雑さの紹介 と 課題内在性負荷‧課題外在性負荷 2. 弊社の「会員システム」の簡単な紹介
3. 「休会」の設計はイケてなかったのか? 4. モデルの⽬的と安定依存の原則(SDP) ※ リファクタリング というより “リ”アーキテクト や “リ”モデリング って表現が正しい RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 20 / 32
22 · PURPOSE AND MEANS 考察 - 「休会」の設計はイケてなかったのか? • •
• • • • サブスクを⽌める仕組みを作っていたので、サブスクが関係ない期間の対 応はできなかった 特別休会って要件が出たタイミングでモデリングを⾒直すべきだったのは ⼤前提そう🙇 「サブスクを⽌める期間を作り、その期間を休会と呼ぶ」が間違いだった 「休会の期間を作り、その期間はサブスクが⽌まる」が正しかったんじゃ ないか 例えば「給与の振り込みを⽌める期間を作り、その期間を休職と呼ぶ」は 明らかにおかしい ⽬的に則したモデルが存在せず、⼿段に則したモデルのみ設計をしていた のではないか RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 22 / 32
24 · AGENDA 話すこと 1. 複雑さの紹介 と 課題内在性負荷‧課題外在性負荷 2. 弊社の「会員システム」の簡単な紹介
3. 「休会」の設計はイケてなかったのか? 4. モデルの⽬的と安定依存の原則(SDP) ※ リファクタリング というより “リ”アーキテクト や “リ”モデリング って表現が正しい RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 24 / 32
25 · DOMAIN DISCOVERY 意図がドメインモデルの発⾒を促す • • • • •
• メールアドレス または 電話番号を 必須にしたい → or 条件でバリデーション🙅 「メールアドレス または 電話番号 を必須にしたい」のはなぜか? 「最低1つは運営からのメッセージ が送信できる連絡先が欲しいから」 → 連絡先モデルを必須にする🙆 ドメインの発⾒! 参考: スケールする要求を⽀える仕様の「意図」と「直交性」 RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 25 / 32
26 · PURPOSE AND MEANS ⽬的を発⾒して、ドメインモデルを発⾒する ⽬的 「なぜ?」と聞く なぜ⽌める? →
休職しているから 休職している 期間を持つ状態 ⼿段 給与の振込を⽌める なぜ休職? → 給与を⽌めたいから、とは⾔わない 操作 なぜ⽌める? → 休会しているから 休会している 在籍したまま、 スタンプの無い期間 定期課⾦を⽌める なぜ休会? → 課⾦を⽌めたいから、とは⾔わない RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) ⽉額プランでの操作 26 / 32
29 · DEPENDENCY DIRECTION ⽬的を発⾒していたが、⼿段をモデリングしていた 目的 手段 • • 商品を届ける
宅配便で送 る 店舗で受け 渡す 休会する 自ら運ぶ 定期課金を 停止 有効な期間 を延長する 目的は、手段を選べるが、手段は、上位の目的を知らなくても、自分の責務を果た せばよい 手段は目的に比べて変化、増減がしやすい RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 29 / 32
安定依存の原則(SDP) 【安定度の⾼い⽅向に依存すること】 変動を想定したコンポーネントは、変化しづらいコ ンポーネントから依存されてはいけない。変更が難 しくなってしまうからだ。 参考: Clean Architechtur = 目的(安定)が手段(変化しやすい
)に依存してはいけない RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 30 / 32
29 · DEPENDENCY DIRECTION ⽬的(安定)が⼿段(変化しやすい)に依存してはいけない • • • • 「休会(=目的)」が「定期課金(手段)」に依存するのが良くなかった
目的を知れば正しいドメインを発見できる 手段よりも安定したドメインに依存できるので、拡張しやすい 新しい機能にも対応しやすくなる RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 29 / 32
31 · TAKEAWAYS まとめ 課題内在性負荷と言う前に要件と意図を聞いてちゃんとモデリングしよう! 1 課題内在性負荷 と思っている仕様も疑う⽬を持とう 2 要求の意図を⾒つけてモデルを発⾒しよう
3 ⼿段は⽬的より変わりやすい だから、⽬的を⼿段の都合に依存させないようにしよう RailsTokyo #6 ‧ モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった(?) 31 / 32