「設計の不備」はどこから生まれ、いつ直すべきか — 設計見直しの優先順位付け
設計の不備を「いつか直す」と言い続けているうちに、開発が止まるほど深刻な技術負債になる——スタートアップでよく起きるパターンです。一方で、すべての設計問題を直そうとするのもリソースの無駄遣いです。放置してよい問題を直し、本当に危険な問題を後回しにしているケースも少なくありません。
本稿では、設計の不備が生まれる典型シナリオを整理し、「直すべき設計」と「放置してよい設計」を見分けるための判断軸を示します。リファクタ・作り直し・許容の3択をどう選ぶか、そして設計見直しを経営・投資判断に翻訳する方法まで扱います。CTO不在のスタートアップ経営者・PM・エンジニアと、VC のバリューアップ担当者を主な読者として想定しています。
設計の不備が生まれる3つの典型シナリオ
設計の不備には「悪意」はありません。当時は合理的だった判断が、状況の変化によって「不備」に変わるケースがほとんどです。大きく3つのシナリオに分類できます。
① 要求の変化(最多)
最初に設計した時点では想定していなかった機能が追加され、既存の設計に無理な拡張を続けた結果、整合性が崩れるパターンです。
例として、ユーザー数百人のMVP(最小実行可能製品)向けに設計したデータベーススキーマに、後からマルチテナント(複数企業が同一システムを使う)要件が加わるケースがあります。MVPの段階では user_id でデータを分離すれば十分でしたが、テナントごとの権限管理・請求分離・データ隔離が必要になると、既存スキーマへのパッチ対応が限界を迎えます。
このパターンは悪くない初期設計からスタートしているため、「いつ設計を見直すべきだったか」の判断が難しいという特徴があります。
② 初期の妥協(速度トレードオフ)
プロダクトを早く出すために意図的に「後で直す」前提で作ったが、直す機会が来なかったパターンです。スタートアップでは「動けばいい」という判断が正しい局面がありますが、「動いている間は触らない」という慣性が働くため、負債が蓄積しがちです。
典型例は、認証ロジックを複数のコントローラーに直接書いていて、セキュリティポリシーを変更するたびに複数箇所を修正しなければならない状態です。初期は「コピペでもいいから早く出す」という判断でしたが、エンジニアが増え、変更頻度が上がると、修正漏れがセキュリティリスクになります。
③ 知識不足(成長による乖離)
設計した当時の知識・経験では最善でも、チームや事業の成長に伴って設計の限界が見えてくるパターンです。
初期メンバーがWebアプリ開発経験3年で設計したシステムが、5年目に機械学習パイプラインとの統合・リアルタイム処理・大規模データ分析という要件を迎えたとき、初期設計の制約が足かせになることがあります。これは設計者を責める話ではなく、事業が成長した証でもあります。
「直すべき設計」と「放置してよい設計」の見分け方
設計の不備が存在することは、多くの場合把握できます。問題は「すべてを直す時間もリソースもない」という現実です。何を直して何を放置するかの判断軸として、影響度と変更頻度の2軸を使います。
影響度の判断基準
「壊れたときに何が起きるか」で判断します。
- 高影響度: 決済・認証・コアのビジネスロジック、SLAに直結する部分、データの整合性に関わる部分
- 低影響度: 管理ツール、ログの出力形式、内部向けの集計処理
変更頻度の判断基準
Gitのコミット履歴を見ると客観的に判断できます。「過去6ヶ月で何回変更されたか」を確認します。週1回以上の変更があるコードは「高変更頻度」と考えてよいでしょう。
リファクタ vs 作り直し vs 許容:判断マトリクス
設計の不備を「直す」と決めた場合、さらに3つの選択肢があります。リファクタリング(既存コードを改善)、作り直し(一から書き直す)、許容(現状維持で問題を受け入れる)です。
| 判断軸 | リファクタ向き | 作り直し向き | 許容向き |
|---|---|---|---|
| 既存コードの理解しやすさ | 読めば理解できる | 理解するより書き直す方が早い | どちらでもよい |
| テストの有無 | テストがある | テストがなく追加も困難 | — |
| 問題の範囲 | 部分的 | システム全体に波及している | 局所的で広がらない |
| 残存価値 | ロジック自体は正しい | 設計の前提から間違っている | コストが便益を上回る |
| リスク許容 | 段階的に変更できる | 段階的変更が困難 | リスクを受け入れられる |
リファクタリングを選ぶとき
既存のコードが「なんとか読める」レベルで、テストが存在し、問題が局所的な場合です。既存ロジックを維持しながら構造を整理する という作業なので、段階的に進められます。
重要なのは「テストなしのリファクタリングはしない」という原則です。テストがない状態でコードの構造を変えると、別のバグを生む確率が高まります。リファクタリング前にテストを追加してから着手します。
作り直しを選ぶとき
「このコードを読んで直すより、ゼロから書いた方が早い」という状態が目安です。ただし、作り直しはリスクが高い選択肢です。
Joel Spolskyが「過去最大の失敗」と呼んだNetscapeの完全書き直しの例が示すように、動いているシステムを一から書き直すと、「見えていなかった仕様」が大量に失われます。ユーザーが気づいていないバグ修正、エッジケースへの対応、長年運用で積み上げてきた暗黙の知識——これらがすべて消える覚悟が必要です。
作り直しを選ぶ場合は、段階的な移行戦略を取ります。旧システムと新システムを並走させ、機能ごとに切り替えていくアプローチです(Strangler Fig パターン)。一度に全部を切り替えるのは避けるべきです。
許容を選ぶとき
「直すコストが、放置し続けるコストより高い」と判断できる場合です。
具体的には、影響度が低く、変更頻度も低い(④のゾーン)かつ、その機能自体が廃止予定または事業上の重要度が低下しているケースです。完璧主義的に「設計上の問題があるから直す」という動機での改善は、ROIが低くなりがちです。
エンジニアが陥りやすい「完璧主義」と「綺麗好き」の罠
技術的に丁寧なエンジニアほど、「コードが汚い」状態を放置できない感覚を持ちます。これ自体は良い感性ですが、事業の優先度とのバランスを欠くと問題になります。
よく見られるのが「触る予定のないコードのリファクタリング」です。変更頻度が低く影響度も低いコードを「気になるから直す」という理由で改善すると、バグを混入させるリスクと改善コストだけが発生し、得られるのは「すっきり感」だけです。「美しいコード」を作ることが目的化し、プロダクトの進化に貢献しないリファクタリングがスタートアップでは特に命取りになります。
また、Boy Scout Rule の「来たときより少しきれいに」は正しい原則ですが、「触るものすべてを完璧にする」と解釈すると、機能開発が何倍もの時間かかるようになります。「少しきれいに」の範囲は、その変更に直接関係する箇所に限定することが重要です。
「直さない」という意思決定を明示的に記録することも有効な対策です。問題の存在は把握しているが今の優先度では手をつけない、と判断した場合、コードコメントやTODOチケットに理由とともに残します。こうすることで「なぜこうなっているか」がチーム全体に伝わり、後から合流したエンジニアが文脈なしに「これは直すべき」と判断して着手するのを防げます。
影響度 × 変更頻度で優先順位を付ける実践
実際に優先順位を付けるには、以下のステップを踏みます。
ステップ1:設計の不備を洗い出す
エンジニアに「直したいコードはどこか」を聞くのが最速です。現場のエンジニアは問題箇所を把握しています。追加で以下のデータを集めます。
- Gitのコミット履歴で変更頻度の高いファイルを抽出(
git log --format="%f" --name-only | sort | uniq -c | sort -rn | head -20等) - バグ報告の集中しているコンポーネント
- コードレビューでの指摘が多い箇所
ステップ2:影響度を評価する
事業視点で判断します。「このコードが壊れたら、ユーザー・売上・SLAに何が起きるか」を一言で表現します。
エンジニアが「重要だ」と感じている部分が、事業的には「あまり使われていない機能」だったことはよくあります。経営者・PM・エンジニアが一緒に評価することで、技術的重要度と事業的重要度のギャップを埋められます。
ステップ3:マトリクスに配置して優先順位を決める
上の図1のマトリクスに各問題を配置し、①のゾーンから順番に改善を計画します。
ステップ4:改善をスプリントに組み込む
設計改善のために「専用のスプリント」を設けることはほとんど機能しません。日常の開発の中に組み込む方が現実的です。
一般的な手法は「Boy Scout Rule(ボーイスカウトの原則)」です。コードに触るたびに、来たときより少しきれいにして帰る。機能開発のついでに関連するリファクタリングを行うことで、設計改善が自然と進みます。
設計見直しを事業判断に翻訳する
設計の不備を「直すべきか」の判断は、最終的には事業トレードオフです。以下のフレームワークで翻訳できます。
技術コストを「開発速度」と「リスク」に変換する
エンジニアが「このコードは設計が悪いから直したい」と言っても、経営者やVCには伝わりにくいです。以下の形で言い換えます。
ビフォー(技術語):
「認証モジュールが密結合していて、変更のたびに全機能への影響を確認しなければならない」
アフター(事業語):
「ログイン方法を変えるたびに2週間かかっている。競合が3日で実装している機能に、うちは3倍の時間をかけている。設計を改善すると、3日で対応できるようになる」
この翻訳は、CTOがいないスタートアップの技術意思決定でも触れているように、技術的な意思決定を経営判断として扱うために重要な習慣です。
「何もしないコスト」を計算する
設計改善の提案は「◯◯円 / ◯ヶ月かかる」という形で出てくることが多いですが、比較対象は「現状維持のコスト」でなければなりません。
| 項目 | 設計改善(初期投資) | 現状維持(継続コスト) |
|---|---|---|
| 工数 | 2週間の改善作業 | 毎回2日増し × 月4回 = 月8日 |
| リスク | 移行中の一時的な不安定 | 変更のたびにバグリスク |
| 3ヶ月後 | 変更コストが1/3に | さらに悪化 |
| 判断 | 3ヶ月で回収できる投資 | 放置するほど高くつく |
このような試算を作ることで、設計改善の優先度を「感覚」ではなく「数字」で議論できるようになります。
VC バリューアップ担当者の視点
投資先の技術状態を評価する立場から見ると、設計の不備は以下のシグナルとして読み取れます。
- 開発速度の低下: 機能開発のペースが競合より遅い場合、設計の問題が原因の一部である可能性が高い
- エンジニア離職の兆候: 「コードが汚くて開発が辛い」という理由での離職は、設計の問題を放置してきた結果として現れやすい
- バグの繰り返し: 同種のバグが繰り返し発生する場合、根本的な設計問題が放置されているシグナル
技術負債の評価フレームワークについては「技術負債」の正体とスタートアップで問題になるパターンで体系的に整理しています。スタートアップの技術組織全体の評価方法についてはエンジニア組織の健全性をどう評価するかも参照ください。
まとめ
設計の不備への対処を整理します。
| ステップ | 問い | アクション |
|---|---|---|
| 発見 | どこに不備があるか | エンジニアへのヒアリング + Gitコミット履歴の集計 |
| 評価 | 直すべきか放置してよいか | 影響度 × 変更頻度のマトリクスで分類 |
| 手段選択 | どう直すか | リファクタ・作り直し・許容の判断マトリクス |
| 翻訳 | 経営・投資判断に落とす | 開発速度と「何もしないコスト」で比較 |
| 実行 | いつ・どう進めるか | Boy Scout Rule + 機能開発への組み込み |
「すべての設計不備を直す」のは理想であり、現実ではありません。重要なのは、放置コストが最も高い問題を特定して、そこから手をつけることです。設計見直しを「技術者の美意識」ではなく「事業投資の判断」として扱うことで、エンジニアと経営者・投資家の間に共通言語が生まれます。
よくある質問
Q. 設計の不備の改善は、エンジニア以外が判断できますか?
「どこに問題があるか」の発見はエンジニアが必要ですが、「何を優先して直すか」の判断は、影響度(事業インパクト)の評価を含むため、経営者・PMが関与できます。「この機能が壊れたらどれくらいまずいか」は非エンジニアでも判断できる問いです。
Q. リファクタリングをするタイミングがわかりません
「この機能を変更しようとしたら、想定外に時間がかかった」というタイミングが最適です。変更しようとした箇所に問題があることが確認でき、改善のモチベーションもあります。定期的な「リファクタリングスプリント」より、機能開発のタイミングに組み込む方が持続します。
Q. 作り直しとリファクタリングの選択基準がわかりません
「このコードを読んで直すのに何時間かかるか」と「ゼロから書いたら何時間かかるか」を比べます。書き直しの方が速いと感じたら作り直しの候補です。ただし、作り直しは「見えていた仕様」以外に「暗黙の仕様」も失うリスクがあるため、その分の工数を加算して判断します。