Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
モノリスなプロダクトの「ほどよい」リプレイス戦略 / A "Just Right" ...
Search
コドモン開発チーム
June 01, 2026
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モノリスなプロダクトの「ほどよい」リプレイス戦略 / A "Just Right" Replacement Strategy for Monolithic Products
コドモン開発チーム
June 01, 2026
More Decks by コドモン開発チーム
See All by コドモン開発チーム
アラート疲れからの脱却 - リソースタグで仕分けるSlack通知戦略 / Breaking Free from Alert Fatigue – A Slack Notification Strategy Using Resource Tags for Routing
codmoninc
0
27
SREに優しいTerraform構成 modulesとstateの組み方 / terraform-modules-state-for-sre
codmoninc
0
340
Don't Just Patch — MOTTAINAI! Learn Security from Laravel CVE Diffs
codmoninc
0
230
ソースコードで比較する React / Vue / Svelte の セキュリティ設計思想 / security design philosophy react vue svelte
codmoninc
5
630
少人数SREチームが、長寿なシステムを構築・運用するための取り組み / Efforts by a Small SRE Team to Build and Operate Long-Lived Systems
codmoninc
0
330
フルリモートのその先へ〜パパね、いつも家にいるけどちゃんとこうして働いてるよ〜 / Beyond Full Remote
codmoninc
0
640
多様な働き方を支えるチーム開発カルチャーと 今後の展望 / Team Development Culture Supporting Diverse Workstyles and Future Outlook
codmoninc
0
550
ペアプロ未経験・未知のスキル領域・フルリモートからでも挑戦できる? 40代転職者の実態 / pair-programming-remote-career-change
codmoninc
0
560
EMが「推し本」を語る会〜アジャイルレトロスペクティブズ第2版〜 / recommended-book_agile-retrospectives
codmoninc
0
96
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
エンジニアに許された特別な時間の終わり
watany
107
250k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
260
Optimizing for Happiness
mojombo
378
71k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
230
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
460
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
550
Transcript
2026年5月30日 株式会社コドモン モノリスなプロダクトの 「ほどよい」リプレイス戦略
2 経歴 プロダクト開発チームでEMとして邁進中。主に写真販売の機能を開 発しています。先週アイコンに合わせるために前髪切りました。 一昨年から産育休を取得して、昨年9月に戻ってきました。あらため て保育園のありがたみを噛み締める日々です。 自己紹介 うらなか 2021.07 コドモンに開発エンジニアとして入社
2021.10 EMにチャレンジ。組織の色々を整備する 2024.08 産休取得 2025.09 復職
3 経歴 所属:エンジニア・写真販売機能 国籍:ブルガリア 在留資格満了日まであと:4年11ヶ月 自己紹介 ディミトロフ チャブダール 2014.03 入国
2021.08 コドモンに開発エンジニアとして入社 2023.01 写真販売機能チームにジョイン
プロダクト開発、やってますでしょうか
プロダクトで事業を推進したい!
ひいては、ユーザーに価値を届けたい!
7 どんなプロダクトだったらハッピー? • ユーザーのペインを解消している/ユーザーにとって価値がある • バグがない/バグっててもすぐ直せる • すぐに機能追加できる • etc...
→ つまり、事業の変化に合わせられる程度に「きれい」なソフトウェア
8 目次 1. リプレイスは目的ではない 2. 「ほどよい」リプレイス計画の立て方 3. ストラングラーフィグパターンでのリプレイスの実例
われわれのプロダクトの状況
10 こんなプロダクトを開発しています
11 • 子ども施設職員の業務を支援するWeb/モバイルアプリケーション • 毎朝の保護者からの電話連絡/各家庭への書類配布/保育料の集金、などなど 施設職員さんの業務負担はあげればキリがありません • このような業務負担を軽減するためのプロダクトです こんなプロダクトを開発しています
12 こんなプロダクトを開発しています
13 • 施設での様子を保護者に届ける、写真共有販売機能 • 写真を廊下に掲示/印刷屋さんへのデータ納付/集金etc... • このような業務負担なく、施設職員さんの「子どものすがたを届けたい」 という気持ちに応える機能を開発しています こんなプロダクトを開発しています
14 10年選手のプロダクトです • 「早くたくさん機能を作る」を優先してきた過去 • DB~バックエンド~フロントまで、幅広くいわゆる「技術負債」がある状態 • 適切ではない構造のテーブル定義がフロントに露出している。 当然、ドメインモデルは存在しない。
テーブル定義変えたい? アクセス箇所を洗い出そう! • ちょっとした変更にもすごく気を使う。このグローバル変数参照されすぎ〜 • 実質スクリプトなPHPとJSファイル。とあるControllerは5000行!
素早く&安全に変更しにくいプロダクト
16 再度目次 1. リプレイスは目的ではない 2. 「ほどよい」リプレイス計画の立て方 3. ストラングラーフィグパターンでのリプレイスの実例
もしみなさんがわれわれのプロダクトを 開発することになったら?
リプレイス!!
したくなりますよね
20 ぜーんぶリプレイスできたら • 最適なテーブル定義 • 素敵なクラス設計 • 当然モダンな言語やフレームワークを使って…… • リプレイスしちゃえば色々簡単になりそうなのになあ
21 現実 • リプレイス、一体何ヶ月かかるんだろう その間、現行機能にどうしても改修が必要になったら? その間、プロダクトの改善は完全停止でいいの? • 範囲を絞りたいけど、結合度が高すぎて影響が読めない…… 増え続けるストーリーポイント、伸びていく見積もり、口角が下がる事業部
• リプレイスして一度リセットできても、そのきれいさは維持できる?
なによりも
コドモンさん、写真の価格設定を 全箇所Repositoryから参照する ようリファクタしたらしいわよ あら、コドモン以外に乗り 換えは考えられないわね
リプレイスだけではユーザーに価値は届かない
リプレイス≠目的、リプレイス=手段
リプレイスという手段が先行するのは 「ほどよく」ない
27 もう一度目次 1. リプレイスは目的ではない 2. 「ほどよい」リプレイス計画の立て方 3. ストラングラーフィグパターンでのリプレイスの実例
28 もう一度目次 1. リプレイスは目的ではない 2. 「ほどよい」リプレイス計画の立て方 3. ストラングラーフィグパターンでのリプレイスの実例
29 • とにかく変更しにくい • リプレイスするから改善止めます、というわけにはいかない。 • 事業目標達成のためのプロダクトロードマップがある。これは開発したい。 • でも今のままのコードベースで新しく機能開発すると
新たな負債を生んでしまう……😭 あらためて、プロダクトの状況
葛藤
「ほどよく」きれいにやれないものか
32 ほどよさ • 別に全部を全部リプレイスしたいわけではない • かといって、コードベースの健全さを度外視して 機能追加だけしたいわけでもない • 今後も変更多そうなところだけでもせめてきれいにしながらできたらな〜
33 せめてどこがきれいなら良いのか?
34 どこを変更できれば良いのか? • コアドメインが価値を産む • コアドメインが変更に強ければ、事業の変化についていけるはず • 逆にそれ以外は最悪システム障害を起こさなければ問題なし、と割り切れる → コアドメインを特定するために、ドメインエキスパートに相談
35 イベントストーミングしました 施設の設定 写真の公開 写真の購入 写真の印刷 利益の還元 事業部のxさん、ここでこういうことできたら KPIめっちゃ改善するって言ってたな〜
36 イベントストーミング、どういう成り行きで? • もともと、プロダクトに対して課題感を抱いていた • 幸い、事業部にいわゆる「技術負債」への理解と共感があった • DDDやっていこう! という開発チームの雰囲気もあった •
せっかくだしセオリー通り、開発チーム以外も巻き込んでみた
どこがコアドメインなのかわかってきた
38 • とにかく変更しにくい • リプレイスするから改善止めます、というわけにはいかない。 • 事業目標達成のためのプロダクトロードマップがある。これは開発したい。 • でも今のままのコードベースで新しく機能開発すると
新たな負債を生んでしまう……😭 あらためて、プロダクトの状況(再掲)
あらためてロードマップ眺めてみると
40 • 「この辺のモデルがコード上できれいになってると事業上拡張性ありそう」 • 「機能開発の上できれいにしたいと思ってたけどサブドメインっぽい」 • 「せっかくきれいにするならここは順番入れ替えた方がコスパいいかも?」 どこにパワーをかけるべきか気づける
41 あらためて「ほどよさ」 • 機能追加/改善はもちろん重要 • それを続けられるようにプロダクトを整えることももちろん重要 • 事業の変化だけでなく、コードベースの都合も考慮して ロードマップを組み直し続けられたらベスト
42 「ほどよい」リプレイス計画の立て方 まとめ • リプレイスという手段を選択すべきときはある、しかし目的化はNG • コアドメインが価値を産む。自分たちにとって最も重要な領域がどこかを 把握しておく。 ここを変更に強くするためのコードベースの改善を検討する。 •
プロダクトロードマップを日々眺める。必要に応じて順番を入れ替える。 コードベースの改善と機能開発の二兎を得ることを目指す。
結局どうやるの
44 目次 1. リプレイスは目的ではない 2. 「ほどよい」リプレイス計画の立て方 3. ストラングラーフィグパターンでのリプレイスの実例
機能開発しながら「きれい」にできたら最高〜
二兎、追いたいですよね
ということで、採用されたのが
48 ストラングラーフィグパターン • システム全体をリプレイスするのではなく、 要所を少しずつ新しくしていく • 古いソースと新しいソースの間には腐敗防止層を 置いて、レガシーの複雑さを隠蔽する
※ 狭義では、クライアントからのリクエストを新旧システムに振り分ける実装を指す 言葉のようですが、今日はMartin Fowlerのサイトに記載された広義の意味で扱いま す ※ 画像はイチジクではなく、いかにもイチジクがありそうだけどなかった八丈島の光 景です(先々週行きました)。素敵なところなのでぜひ。
実際の事例をご紹介します
現行システム
51 登場するシステム • PHP現行モノリス 〜10歳 • Kotlinベースの写真共有専用サービス 〜3歳 写真販売
52 登場するシステム • Kotlinベースの写真共有販売専用サービス 3歳 ◦ リリースの独立 ◦ 非機能要件がちがう ◦ 型定義、コンパイルの恩恵
Kotlinを選定 → 機能提供がてら、「ほどよく」リプレイス
ユーザージャーニー
54 登場するユーザージャーニー アルバムの写真を閲覧し、ダウンロード/印刷して思い出として残せる 印刷 ダウンロード
55 登場するユーザージャーニー アルバムの写真は保育施設の職員さんがアップロードして公開してくれる アルバム
事例:思い出として残せる写真を増やす
57 事例:思い出として残せる写真を増やす アルバムという形式で保育士の方が用意してくれる ただ、子供の写真は他の機能からもアップロードされる *イメージ アルバム 機能A 機能B
58 事例:思い出として残せる写真を増やす 他の場面からの写真も思い出として残せるようにしたい アルバム 機能A
写真共有のコアドメイン
60 写真共有のコアドメイン 写真共有のコアドメイン 保育園から送られてくる、 普段見ることのできない「園でのすがた」
61 61 割と複雑な判定要素 • 宛先の種類 ◦ 個人宛 ◦ クラス宛 (さくら組、とら組) •
卒園済み/入園前 • 園児のクラスの在籍履歴 • 公開期限 • … お子様が複数人いるケース • 異なる園に所属 • 同じ園に所属 • 片方だけ卒園済み • … 公開対象の判定
62 モデル化 プロパティ • 公開期限 • 添付されている写真 ロジック • 公開対象の判定
Domain Service AvailablePhoto Collections 保護者に対して公開されている写真
現行システムの状況
64 コアドメインの現行システムの状況 1 • モデルは不在 • その保護者に公開されているかを判定する複雑なロジックが 複数箇所で定義されている
65 コアドメインの現行システムの状況 1 • モデルは不在 • その保護者に公開されているかを判定する複雑なロジックが 複数箇所で定義されている
66 66 割と複雑な判定要素 • 宛先の種類 ◦ 個人宛 ◦ クラス宛 (さくら組、とら組) •
卒園済み/入園前 • 園児のクラスの在籍履歴 • 公開期限 • … お子様が複数人いるケース • 異なる園に所属 • 同じ園に所属 • 片方だけ卒園済み • … 公開対象の判定
67 コアドメインの現行システムの状況 1 • モデルは不在 • その保護者に公開されているかを判定する複雑なロジックが 複数箇所で定義されている
68 コアドメインの現行システムの状況 2 • データベースと密結合 • 例:公開期限はアルバムテーブルのxxカラムの値そのまま
現行システムで実現する場合
70 事例:思い出として残せる写真を増やす • 他の場面からの写真も思い出として残せるようにしたい アルバム 機能A
71 事例:思い出として残せる写真を増やす • 他の場面からの写真も思い出として残せるようにしたい アルバム 機能A 公開ロジックがこの機能のため のテーブルに依存しているが、 この機能のテーブルからも データを持ってきたい!
72 各箇所に写真の由来となる機能ごとの分岐を追加する 現行システムで実現する場合
73 各箇所に写真の由来となる機能ごとの分岐を追加する 現行システムで実現する場合 if 由来が機能A: …
74 コアドメインの現行システムの状況 • データベースと密結合 • 例:機能Aの場合は公開期限はテーブルAのこのカラム
75 • 重複する複雑なロジックの各箇所に写真の由来の分岐を追加する • 変更のリスクは大きく、テストは難易度が高い • 将来的な拡張性は難しいまま 現行システムで実現する場合
76 • もしくはモデルを参照する形にリファクタリングする • しかしこの場合も実装コストがそれなり。。 →新規システムにリプレイスしてから実現する 現行システムで実現する場合
実装方針
78 1. 写真共有専用システムでモデルを実装 2. 既存の機能を新規システムにリプレイス 3. 機能の拡張(新しい写真も思い出に追加!) 実装方針
新規システムでモデルを実装
80 モデル化 プロパティ • 公開期限 • 添付されている写真 ロジック • 公開対象の判定
Domain Service AvailablePhoto Collections 保護者に対して公開されている写真
81 モデル化: 具象クラスで異なる由来を表現 • 「現在保護者に対して提供されている写真」というインタフェース • 異なる由来の写真を具象クラスの実装で表現 <<interface>> IAvailablePhotoCollections AlbumPhotoCollections
(由来: アルバム機能)
82 モデル化: 拡張性 思い出として残せる写真を増やすには • 具象クラスの実装 • 変換ロジックの実装 • だけで済む (はず) <<interface>>
IAvailablePhotoCollections AlbumPhotoCollections (由来: アルバム機能) ServiceAPhotoCollections (由来: 機能A) 既存機能 拡張機能
105 • システム外で作成される「写真」なので写真のIDをビジネスキーで表現する モデル化: 写真IDの定義 PhotoCollections PhotoID PhotoIDの構成 {外部ID}_{写真のパス}
「きれい」なモデルはできたはいいが、 リプレイスしないといけない
ストラングラーパターンでのリプレイスの進め方
86 1. 新規システムでモデルを実装 2. 既存の機能を新規システムにリプレイス 3. 機能の拡張(新しい写真も思い出に追加!) 実装方針
87 ストラングラーパターンでの進め方 Before
88 ストラングラーパターンでの進め方 Before After
89 • 要所にフォーカスすることで ◦ 優先度高く実施したい施策のリードタイムを縮小したい ストラングラーパターンでの進め方
90 • 一部にフォーカスすることで ◦ 今改善を試みていない箇所は既存のままにできる ▪ 決済 ▪ メール送信 ▪
印刷 ▪ 。。。 ストラングラーパターンでの進め方
91 このようなシステムにしていきます ストラングラーパターンでの進め方 Domain Service AvailablePhoto Collections
92 before ストラングラーパターンでの進め方
93 before after ストラングラーパターンでの進め方
94 before after ストラングラーパターンでの進め方 ACL ACL
95 ストラングラーパターンでの進め方 • 新規に実装された「モデル」
96 ストラングラーパターンでの進め方 • 新規に実装された「モデル」 • 現行システムに必要な データ形式
97 元のデータと同じものができるので、前後の機能をそのまま使える ストラングラーパターンでの進め方 購入データは 今まで通り
98 元のデータと同じものができるので、前後の機能をそのまま使える ストラングラーパターンでの進め方 履歴、集計、印刷、、 も今まで通り 購入データは 今まで通り
🎉
新機能リリース
101 1. 新規システムでモデルを実装 2. 既存の機能を新規システムにリプレイス 3. 機能の拡張(新しい写真も思い出に追加!) 実装方針
102 事例:思い出として残せる写真を増やす アルバムという形式で保育士の方が用意してくれる ただ、子供の写真は他の機能からもアップロードされる *イメージ アルバム 機能A 機能B
103 103 事例:思い出として残せる写真を増やす • 「保護者に対して提供されている写真」というインタフェース • 異なる由来の写真を具象クラスの実装で表現 <<interface>> IAvailablePhotoCollections AlbumPhotoCollections
(由来: アルバム機能)
104 104 • 「保護者に対して提供されている写真」というインタフェース • 異なる由来の写真を具象クラスの実装で表現 <<interface>> IAvailablePhotoCollections AlbumPhotoCollections (由来:
アルバム機能) ServiceAPhotoCollections 機能A 事例:思い出として残せる写真を増やす
🎉🎉
まなび
107 • ✅ コアドメインにエンジニアリングリソースを使うとペイしやすい ◦ 新しくやりたい施策がコアドメインに関連することが多い(主観) 学び 1
コアドメイン
109 • ✅ リプレイス範囲を絞ると3ヶ月以内くらいで開発できる 学び 2
110 • ✅ リプレイス範囲を絞ると3ヶ月以内くらいで開発できる ◦ 機能リリースまでのリードタイム 学び 2
111 • ✅ リプレイス範囲を絞ると3ヶ月以内くらいで開発できる ◦ 小さく転べる 学び 2
112 • ⛔ 複数システムを跨ぐ状態は認知負荷があがる 学び 3
113 • ⛔ 複数システムを跨ぐ状態は認知負荷があがる ◦ 複数箇所に改修・リリースが必要 学び 3
114 • ⛔ 結果整合性の仕組みが必要になる 学び 4
結論
116 • 銀の弾丸はなかった 結論
117 • 銀の弾丸はなかった ◦ 。。けど事業を促進する「ほどよい」リプレイスはできる 結論
118 まとめ、あらためて「ほどよく」やっていくということ • ユーザーに届く価値(あるいは事業の成果)を最大化する • やりすぎない・必要なところだけ整える • しかし機能追加だけを追い求めない。 コードベースの問題や、SLOに対してのリスクなど、開発者だけが
知っていることもあるはず。 • 全員が気持ちよく譲りあって最高のロードマップを作り続け、実現し続ける ※ 今日は時間の都合で入りきらなかったのですが、このプロセスの中で「開発者だけが情報を持っている、SLO的にマ ズいのでなんとかした方がいい箇所」をロードマップに載せる活動も行っています
おまけ
120 今日話せなかったこと • 結果整合性を担保する仕組みや実装の具体について • 複数システムを跨いだときのテストについて • ベイビーステップで進めるためのリリース戦略について
121 我々がうまくやれている前提 • 事業部と信頼関係を築けており、健全なコミュニケーションが取れている (コアドメインの特定/ロードマップの入れ替えの相談などがスムーズ) • わかりやすい事業/プロダクトKPIがあり、 「何を守ればいいか(何を毀損してはいけないか)」が明確 • 事業に対して開発チームが1つなので、ステークホルダーも少ない
• 結合度高いモノリスだが、全く違う機能と結合している箇所は多くない。 ある程度影響をコントロールできた
つまり、意思決定(とその結果)が コントローラブルだった
おわりに
124 計画を立てられたとて • そう簡単にできるなら文句ないわけで • 変更したい部分と、そうでない部分が密結合してるから悲しいわけで • その結合を壊さないように整理してさらに機能改善するなんて大変なわけで
でもその複雑さと戦うのが楽しい という方へ
WEBアプリケーションエンジニア • ユーザーからのフィードバックをもとにした機能改善 • レガシーコードのリファクタリングやリプレイス • 新機機能や新規プロダクトの開発 • 開発生産性向上 SREエンジニア
• プラットフォームエンジニアリングの推進 • オブザーバビリティの組織展開 • システムセキュリティの強化 • AWS環境の設計・構築・運用、システムの可観測性と信頼 性の向上 エンジニアリングマネージャー • 採用・評価運用の改善の推進 • 開発ロードマップの議論の推進 • 開発部全体のプロセス改善の推進 • 自己組織化の促進 やることの例 やることの例 やることの例 126 色々な職種・役割において仲間を募集中です 詳しい開発チームの情報はこちら
ご清聴ありがとうございました
None