実装前に決めること、決めないこと:手戻りを減らす設計の粒度【第3回】
「設計書を書いて」と言われて手が止まるのは、書くべきことが分からないからです。この記事を読み終えると、変えにくいもの(骨組み)だけを先に決め、変えやすいもの(内装)は後回しにするという判断基準を持ち、実装前に10分で確認できるチェックリストを使えるようになります。ジュニアエンジニア向け開発フロー入門シリーズ(全8回)の第3回です。
🎯 テーマの主役:「設計」——骨組みを先に決める技術
今回の主役は設計です。一言で言えば、設計とは「後から変えると高いものだけを、先に決めておく技術」です。
日常の例えで言うなら、家の「骨組み」と「内装」の区別です。家を建てるとき、壁紙や家具は後から変えられます。しかし、柱の位置、配管、配線、耐力壁は、後から変えるのに大工事が要ります。だから住宅の設計では、変えにくいものから先に決めます。壁紙は住みながらでも変えられますが、柱は住んでからでは変えられません。
ソフトウェアも同じです。変数名や関数の中の書き方(内装)は、後からでも変えられます。ところがデータの形、モジュールの境界、外部との約束(インタフェース)は、後から変えると広範囲に影響します。設計の仕事は、これら「柱」にあたるものを先に見極めて決めることです。逆に言えば、柱でないものを先に決めるのは設計ではありません。それは内装の決めすぎで、後で剥がすコストを生みます。
第2回で、受け入れ条件(何を満たすか)が決まりました。今回の設計は、その次の関門である「どう作るか」です。この関門の出口条件は「触る範囲・境界・データの形が決まっていること」でした。この記事では、その「決まっている」の粒度を具体化します。
この関門を通せるようになると、次の3つができるようになります。第一に、「実装前に何を決めればよいか」を自分で判断できること。第二に、設計書を「見せる書類」ではなく「決めるための道具」として使えること。第三に、「この作り方は後で変えにくい/変えやすい」を説明できることです。3つ目は、レビューで必ず聞かれる質問への答えになります。
動機:「設計」が両極端になる理由
ジュニアエンジニアの設計に対する態度は、たいてい両極端に振れます。一方には「設計なんて時間の無駄だ。実装しながら考えればいい」という態度。もう一方には「設計書を完璧に仕上げてからでないと実装してはいけない」という態度です。どちらも、設計の目的を1つに誤解しているところから来ています。
前者の態度で進めると、こうなります。実装を進めながら「このデータ、実は3か所で必要だな」と気づき、その場で処理を足す。別の箇所でも似た処理が必要になり、コピーする。3か月後、同じロジックが7か所に散らばり、1つの仕様変更に7か所の修正が必要になります。設計をサボったのではなく、設計を「実装の中で無自覚に」やってしまったわけです。無自覚に決めたことは、記録もされず、一貫性もありません。
後者の態度で進めると、こうなります。設計書を2週間かけて書き、レビューで「この部分は実装してみないと分からない」と言われる。それでも書類を完成させてから実装に入り、実装してみたら前提が違ったと分かる。設計書は見事でしたが、書くために使った2週間の情報は、実装で得られる情報より少なかったのです。
この記事の仮説はこうです。設計の質は「書類の完成度」ではなく「変えにくいものを正しく見極められているか」で決まる。もしこれが正しければ、設計の作業は「全部を決めること」ではなく、「どれが変えにくいかを見極め、それだけを決めること」になります。
🔍 検証①:決めなかったことは、消えずに実装の中に散らばる
まず、設計を省くと何が起きるのかを正確に見ます。「決めなかったことは、後で決まる」——これは正しいのですが、誰が、どこで、どんな一貫性で決めるかが問題です。
設計をしないまま実装すると、決めていないことは実装のその場その場で決まります。1つ目の機能では「日付は文字列で持とう」と決まり、2つ目の機能では「日付は数値で持とう」と決まり、3つ目の機能では「専用の型を使おう」と決まる。どれも間違いではありませんが、混在すると変換コードが必要になります。変換コードはバグの温床で、テストも倍必要です。
決定的なのは、その場で決めたことが記録されない点です。「なぜ文字列で持つことにしたのか」は誰も覚えていません。半年後、そのコードを読んだ人は「なぜここだけ文字列なのか」を推測するしかなく、推測を間違えると壊します。
| 決めなかったこと | 実装の場で起きること | 半年後に起きること |
|---|---|---|
| 日付の持ち方 | 機能ごとに文字列・数値・型が混在する | 変換コードが増え、比較や並べ替えでバグが出る |
| エラーの返し方 | 例外・戻り値・ログが場当たりに混ざる | エラー処理の漏れが見つからない |
| モジュールの責務 | 同じ処理が複数箇所に書かれる | 1つの仕様変更に7か所の修正が必要になる |
| 外部との約束 | 画面の都合でAPIの形が決まる | 画面を変えるたびにAPIも変わり、利用側が壊れる |
| 状態の持ち方 | 「誰が真実か」が曖昧になる | 画面とデータベースの表示が食い違う |
ここから分かるのは、設計の省略は「省略」ではなく「無自覚な分散決定」だということです。決めなかったのではなく、決める権利を、後から来る無数の実装に配ってしまったのです。設計とは、この分散を防ぐ作業です。
🔍 検証②:変えにくいものと変えやすいものを分ける
次に、何を先に決めるべきかの判断基準を作ります。基準は1つです。「後から変えると、どれだけ広く影響するか」。これを4つの問いに分解すると、実務で使える形になります。
| # | 問い | 「はい」なら | 例 |
|---|---|---|---|
| 1 | 他の人・他のモジュールが依存するか | 先に決める(境界・インタフェース) | APIの入出力、関数の約束、イベントの名前 |
| 2 | データとして保存されるか | 先に決める(形は残り続ける) | テーブルの列、ファイル形式、ログの項目 |
| 3 | 外部に公開するか | 先に決める(相手の予定が変わる) | 公開API、連携仕様、他社に渡すデータ |
| 4 | 変更が同時に何か所に必要か | 多いほど先に決める | 共通処理の置き方、共通の値の持ち方 |
逆に、4つの問いすべてが「いいえ」なら、それは後で決めてよいものです。関数の中の書き方、変数名、ループの回し方、ログの文言——これらは実装中に決めて構いません。設計の時間を、変えやすいものの議論に使うのが最も無駄です。
| 分類 | 例 | 決める時期 | 後から変えたときの影響 |
|---|---|---|---|
| 変えにくい(骨組み) | データの形、モジュールの境界、外部との約束、状態の持ち方 | 実装前 | 広範囲。他の人・保存済みデータ・外部に波及する |
| 中間 | 処理の分割、共通処理の切り出し方、エラー処理の流れ | 実装の初期 | 中程度。リファクタリングで対応できるが、テストが要る |
| 変えやすい(内装) | 変数名、関数の中の書き方、ログ文言、画面の細かい配置 | 実装中・後でも可 | 小さい。影響が内側で閉じる |
🔍 検証③:境界から決める——インタフェース先行
変えにくいものの代表が境界(インタフェース)です。境界とは、モジュールとモジュールの間、システムとシステムの間で交わされる「約束」のことです。「この関数は、この形の値を受け取り、この形の値を返す」「このAPIは、この項目を受け取り、この形式で結果を返す」。
境界を先に決めると、大きな利点があります。第一に、並行して作業できることです。境界が決まっていれば、片側が未完成でも、もう片側を先に作り始められます(未完成の代わりにダミーの応答を返すものを「モック」と呼びます)。第二に、テストが書きやすいこと。境界が決まっていると、境界の前後で別々にテストできます(第6回で扱います)。第三に、変更の影響が予測できること。境界の内側だけを変える変更は、外に影響しません。
境界を決めるときのコツは、「何をするか」ではなく「何を受け取って何を返すか」から書くことです。たとえば「顧客を検索する関数」を作るとき、最初に書くべきは次の3行です。
- 入力:検索語(文字列、必須、最大100文字)
- 出力:顧客の一覧(0件〜最大50件。各顧客はID・名前・メールアドレス)
- 失敗:検索語が空ならエラーを返す。該当0件はエラーではない(空の一覧を返す)
この3行があれば、実装の中身が未完成でも、呼び出す側のコードは書けます。「0件はエラーではない」のような決定は、後から変えると広く影響するので、境界の段階で決めておく価値があります。
なお、境界の決め方には情報隠蔽(information hiding)という古典的な原則があります。1972年のパルナスの論文が原典で、「モジュールは、変わりやすい決定を内側に隠すように分割する」と述べています。50年以上前の提案ですが、「変えにくいものは何か」を軸に分割するという考え方は、今も設計の中心です。
🔍 検証④:図は「迷っている場所」にだけ描く
設計の議論では図が有効ですが、どの図を、どこに描くかで効果が変わります。よくある失敗は、全部の図をきれいに描こうとすることです。目的は会話と思考であって、提出物ではありません。
図にはそれぞれ答えられる問いがあります。目的に合う図を選べば、5分で描けます。
| 図の種類 | 答える問い | 向いている場面 | 描く時間の目安 |
|---|---|---|---|
| 箱と矢印の全体図 | 何が登場し、どれが何を使うか | 新しい機能の全体像を共有する | 5分 |
| データの形(表形式) | 何を、どんな項目で持つか | テーブル設計・APIの入出力 | 10分 |
| 流れの図(フロー) | どの順で何が起きるか | 処理手順・例外の分岐 | 10分 |
| やり取りの順序(シーケンス) | 誰が誰に、どの順で頼むか | 複数の登場人物が絡む処理 | 15分 |
| 状態の遷移 | どんな状態があり、どう移るか | 申込・承認・配送など状態を持つもの | 15分 |
重要なのは、「迷っている場所にだけ描く」という原則です。設計の議論で時間が溶けるのは、すでに全員が合意している部分を丁寧に描いてしまうときです。逆に、意見が割れている部分・判断に自信がない部分は、必ず図にしてください。口頭の説明は、聞き手の頭の中で別々の絵になります。図は、全員の頭の中の絵を1枚に揃える装置です。
🔍 検証⑤:設計判断の記録——「なぜ」を1ページ残す
設計で決めたことのうち、最も失われやすいのが「なぜそう決めたか」です。「日付はISO形式の文字列で持つ」という決定は、コードを見れば分かります。しかし「なぜ数値のタイムスタンプにしなかったのか」は、コードからは分かりません。半年後、この決定を変えようとした人は、理由を知らないまま変更し、過去にその形式を選んだ理由だった問題を再発させます。
この問題への定石が、設計判断の記録(ADR: Architecture Decision Record)です。形式は簡単で、1つの決定につき1ページ、次の3項目を書くだけです。
| 項目 | 書くこと | 例 |
|---|---|---|
| 状況 | どんな問題があり、どんな制約があったか | 日付の比較・並べ替えが機能ごとにバラバラで、バグが繰り返していた |
| 決定 | 何を選んだか | 日付はISO 8601形式の文字列で統一する |
| 理由と代替案 | なぜそれを選び、他に何があり、なぜ退けたか | 数値のタイムスタンプは可読性が低く、運用時の調査が困難。専用の型は既存の保存形式と互換がない |
ADRを書く場所は、リポジトリ内のMarkdownファイル1つ(例:docs/adr/0001-date-format.md)で十分です。書くことの目的は、承認を得ることではなく、未来の誰か(多くの場合、未来の自分)に理由を残すことです。第2回で扱った「たすきの中身=意図と根拠」は、設計の段階ではこのADRがたすきになります。
🔍 検証⑥:過剰設計との線引き——「将来必要かも」で作らない
設計の話をすると、必ず出てくるのが過剰設計の問題です。「将来、他の顧客にも使うかもしれないから、今のうちに汎用的にしておこう」「いずれ別のデータベースに移るかもしれないから、切り替えられる層を作っておこう」。この判断は、たいてい損になります。
理由は単純です。使われなかった抽象化は、純粋な負債だからです。抽象化には必ずコストがかかります(間接層が増え、読む人が追う距離が伸び、テストの組み立てが複雑になる)。そして「将来必要かも」の予測は、当たらないことが多い。XP(エクストリームプログラミング)の文脈で広まったYAGNI(You Aren’t Gonna Need It:それは要らない)という原則は、この状況を指します。
判断の基準は、次の2つです。第一に、いまの受け入れ条件(第2回)で説明できるか。説明できない抽象化は入れない。第二に、使われる時期が見えているか。「来月、必ずこの機能が入る」なら先に作る価値がありますが、「いつか来るかもしれない」なら作りません。判断に迷ったら、作らずに書いておくのが正解です。「この箇所は、複数の顧客で使うことになったら共通化する」とコードコメントやADRに書いておけば、必要なときに判断を再開できます。
| 判断 | 見分け方 | 結果 |
|---|---|---|
| 先に作る(正当) | 受け入れ条件にある。使う時期と担当が見えている | 手戻りが減る |
| 先に作る(過剰) | 「将来使うかも」だけが理由。使う人の予定がない | 読めないコードと、使われない層が残る |
| 後で作る(正当) | いまの要件に不要。判断の再開条件をメモしてある | 必要なときに、必要な分だけ作れる |
| 放置(危険) | 共通化すべき重複が、すでに3か所以上にある | 1つの変更に何か所も直すことになる |
目安として、同じ処理が3か所に現れたら共通化を検討するという経験則(rule of three)がよく使われます。1回目はそのまま書き、2回目は我慢し、3回目で抽象化する——この順番なら、抽象化の形を実例から決められます。逆に1回目から抽象化すると、まだ見ていない2つのケースに合わせて間違った形を作る危険があります。
結果:実装前に10分で確認できる7項目
ここまでの内容を、実装前に確認するチェックリストにまとめます。すべてに「はい」と言えれば、設計の関門は通っています。書類は不要です。答えられることが条件です。
| # | 確認項目 | 「はい」と言えないときにやること |
|---|---|---|
| 1 | 触る範囲を、ファイルやモジュールの名前で挙げられる | 依存関係を1段だけ追って、影響範囲を確認する |
| 2 | データの形(項目・型・必須かどうか)が決まっている | 表形式で書き出す。迷った項目に印を付ける |
| 3 | 境界(入出力と失敗の形)が決まっている | 入力・出力・失敗の3行を書く |
| 4 | 既存の似た処理を探し、再利用するか新規かを決めた | コード検索で似た処理を探す(重複を作らない) |
| 5 | 失敗したときの動作(エラー表示・ログ・再試行)を決めた | 「失敗したらどう見えるか」を1行で書く |
| 6 | 後で変えにくい決定に印を付け、ADRに1行残した | 「状況・決定・理由」の3行を書く |
| 7 | 「決めないこと」を決めた(実装中に決めてよい範囲) | 迷っている箇所を「実装中に判断」と明記する |
このうち最も大事なのは7番です。設計とは、すべてを先に決めることではなく、「ここは決めた」「ここは決めていない(いつ決めるかも決めた)」を区別することです。区別があれば、実装中に「ここはまだ決まっていない」と気づいたときに、立ち止まって相談できます。
考察:設計は「時間の無駄」ではなく「変更コストの前払い」である
ここからは、検証では扱いきれなかった解釈を述べます。設計が軽視される理由を考えると、設計の効果が見えにくいという性質に行き着きます。設計をした場合としなかった場合を比べると、設計をした側は、最初の実装が遅く見えます。ところが、その後の変更で逆転します。設計をした側は1か所を直し、しなかった側は7か所を直す。この差は、変更が来て初めて見えます。
つまり設計は、「変更というイベントに対する保険」です。変更が一度も来なければ、設計のコストは回収されません。では変更は来るのか。第1回で見たとおり、ソフトウェアの要件は変化し続けます。市場、利用者、法規制、依存ライブラリ、チーム。どれかが動けば変更が来ます。変化が来ないソフトウェアは、使われていないソフトウェアです。だから設計は、原則として回収されます。問題は「いつ回収されるか」が見えないことだけです。
この性質から、実務的な結論が導けます。設計のコストは、変更の頻度が見込める箇所に集中させるのが合理的です。決済、認証、データの形、外部連携——変更が起きたときに高くつく箇所は、丁寧に決めます。社内の使い捨てツールや、廃止が決まっている機能は、軽く通します。「すべてを丁寧に」も「すべてを軽く」も、どちらも間違いです。第1回で述べた「関門の重さは、変更の戻しにくさに比例させる」は、設計の粒度でも同じ形で現れます。
そして、AI時代にはこの判断がより重要になると考えられます。AIが実装を速くするほど、設計のまずさが速く露出します。設計が悪いまま実装だけ速くなると、間違った構造が速く積み上がるからです。逆に、設計の関門を正しく通せていれば、AIに実装を任せたときの検証も簡単になります(境界が決まっていれば、テストも自動生成しやすい)。第2回で見た「要件を書く力」と、今回の「変えにくいものを見極める力」は、AIに仕事を渡す時代の基本の型になっていくと考えられます。
📌 注目ポイント
- 設計の実体は「決めること」。設計を省くと、決める権利が実装のあちこちに散らばり、探せない・直せない状態になる
- 決める対象は変えにくいものだけ。判断基準は「依存されるか/保存されるか/公開するか/同時に何か所直すか」の4問
- 変えやすいもの(変数名・書き方)を先に決めるのは設計ではない。議論の時間を溶かす
- 境界(入出力と失敗の形)を先に決めると、並行作業・テスト・変更の予測がすべて楽になる
- 図は迷っている場所にだけ描く。すべての図をきれいに描く必要はない
- 決定の「なぜ」はADRに3行で残す。コードからは理由が読めない
- 「将来必要かも」で抽象化しない。同じ処理が3回現れてから共通化する
- 設計の効果は変更が来て初めて見える。変更が高くつく箇所に集中投資する
💡 活用事例:Python 2から3への移行が教える「変えにくいもの」の重さ
「変えにくいものを後から変えるのは、どれほど高いか」を示す最良の実例が、プログラミング言語Pythonのバージョン2から3への移行です。
Python 3.0は2008年12月にリリースされました。最大の変更点の1つは文字列の扱いで、Python 2では文字列(str)がバイト列として扱われる場面があり、Python 3ではUnicode文字列(テキスト)とバイト列(bytes)が明確に区別されるようになりました。設計者たちは、この区別を曖昧なままにすることをやめ、変えにくい部分を根本から変える決断をしました。
結果、移行には12年以上かかりました。Python 2の最終版である2.7の正式サポート終了は2020年1月1日です(PEP 373で予告され、実際にその日が迎えられました)。移行が長期化した理由は、まさに本記事のテーマです。言語の仕様は、無数のライブラリとアプリケーションが依存する「変えにくいもの」でした。誰かが変えると、依存する全てのコードが影響を受けます。移行ツールや互換ライブラリが作られ、それでも間に合わないプロジェクトが続出しました。
この事例の教訓は2つあります。第一に、変えにくいものの変更は、どれほど優れた設計でも高くつく。だからこそ、新しい設計をするときは「これは後から変えられるか」を先に考える価値があります。第二に、変えにくいと分かっているなら、変えるなら早いほうがよい。Python 2が広く使われてからの変更は、使われていないうちに変えるよりはるかに高くつきました。
開発の現場では、これがそのままデータの形と公開APIに当てはまります。テーブルの列名、外部に公開するAPIの項目名、イベントの名前——これらはPythonの文字列型と同じで、後から変えると、依存する全てを巻き込みます。設計の関門で「これは後から変えられるか」と1回問うだけで、数年後の大工事を防げます。
✅ 要点まとめ
- 設計とは後から変えると高いものだけを先に決める作業。家の柱と壁紙の区別と同じ
- 設計を省くと、決定が実装に無自覚に分散し、探せない・直せない状態になる
- 先に決める対象は依存されるもの・保存されるもの・公開するもの・同時変更が多いもの
- 境界(入出力・失敗の形)を先に決めると、並行作業とテストが楽になる
- 図は迷っている場所にだけ描く。全図をそろえる必要はない
- ADR(状況・決定・理由)を3行残す。コードからは「なぜ」が読めない
- YAGNI。使われない抽象化は負債。共通化は3回目から
- 実装前の7項目チェックで関門を通す。書類ではなく答えられることが条件
- 設計は変更コストの前払い。変更が高くつく箇所に集中させる
🚀 取り込み方:明日から使う3段階
今日(5分でできること):いま取りかかろうとしているタスク1つについて、上の7項目チェックを頭の中でやってみてください。特に3番(境界の入出力と失敗の形)を3行書いてみるのが効果的です。書けない行があれば、それが設計の不足です。わざわざ文書化する必要はなく、チケットのメモ欄やエディタのコメントで構いません。
今週(小さく試す):次の小〜中規模のタスクで、ADRを1つ書いてみてください。リポジトリに docs/adr/ フォルダを作り、0001-◯◯.md という1ページを追加します。「状況・決定・理由」の3項目だけです。プルリクエストの説明欄に書くだけでも代用できます。書きながら「これは後から変えにくい決定だ」と気づく体験が重要です。
今月(定着させる):自分の担当範囲で「これは後から変えられない」ものを1つ選び、それを変えるとしたら何が必要かを調べてみてください。テーブルの列、公開APIの項目、設定ファイルの形式などが候補です。変える場合の影響範囲(どのコード・どの利用者が影響を受けるか)をリストにすると、設計の判断基準が体に入ります。あわせて、コード検索で「同じような処理が3か所以上にある箇所」を1つ探し、共通化の候補としてメモしておきましょう。
🔥 ハマりポイント
その1:設計書は「見せる書類」だと思う
設計書を提出物として捉えると、きれいに書くことが目的化し、判断に迷った箇所を曖昧なまま流すようになります。設計の目的は決めることであり、書類はその記録です。むしろ、迷っている箇所を明示することが最も価値の高い成果です。「ここは2案で迷っています。Aは◯◯、Bは△△」と書いてあれば、レビューの焦点がそこに集まります。
症状:レビューで「ここはどうなっているの?」が繰り返される。原因:迷いを隠して、決まったように書いている。対処:「決めたこと」「決めていないこと」「迷っていること」の3分類で書く。
その2:全部を先に決めようとする
「決め漏れが怖い」という気持ちから、実装の細部まで先に決めようとすると、実装で得られる情報を使えなくなります。たとえば「このループはこう書く」と先に決めても、実装してみると別の書き方が明らかに良い、ということはよくあります。決めるべきは変えにくいものだけで、変えやすいものは実装中に決めるのが合理的です。
症状:設計に時間をかけても、実装で設計が変わる。原因:変えやすいものまで決めている。対処:4つの問い(依存・保存・公開・同時変更)に「いいえ」のものは後回しリストに入れる。
その3:選択肢を1つに絞ってから相談する
「A案でいきます」とだけ伝えると、なぜB案でないのかが分からず、レビュアーは判断できません。すると「Bの方がいいのでは」という指摘から議論が始まり、決まっていたはずの部分まで蒸し返されます。持って行くのは選択肢と理由のセットです。「A案は◯◯の理由で良いと思いますが、△△の懸念があります。B案は逆です」——この形なら、相手は判断だけに集中できます(第2回のSBARと同じ構造です)。
症状:設計レビューで毎回振り出しに戻る。原因:選択肢と理由が共有されていない。対処:決定・代替案・決定理由の3点をセットで出す。
その4:「とりあえず動くように」を設計の代わりにする
「まず動かしてから考える」は、プロトタイプや検証では正しい進め方です。問題は、そのコードがそのまま本番に残ることです。プロトタイプと本番の違いは、後から変えられるかどうかです。使い捨てる前提なら大胆に書き、残す前提なら設計を通す——この区別を最初に宣言しておくと、後の揉め事が減ります。
症状:検証用に書いたコードが、そのまま本番で使われ続ける。原因:「捨てる予定」が共有されていない。対処:コードやチケットに「検証用・本番では作り直す」と明記する。
🔄 代替技術との比較:設計の粒度
設計の粒度には正解がなく、状況によって選ぶものです。3つの水準を比較します。
| 粒度 | やること | 向いている状況 | リスク |
|---|---|---|---|
| 決めなさすぎ | 実装しながら全て決める | 使い捨ての検証。1人だけの小ツール | 決定が散らばり、後から探せない。高速で負債が積み上がる |
| 必要十分(推奨) | 変えにくいもの+境界+失敗の形だけ決める | 通常の機能開発。チームで開発する場合 | 判断に慣れるまで、何が「変えにくい」か迷う |
| 決めすぎ | 内部の書き方・命名・手順まで全て決める | 規制対応で手順の固定が必要な場合 | 実装の自由度が消え、学習を活かせない。書類が目的化する |
設計を表現する手段にも選択肢があります。テキストの文書(検索しやすく、差分が追える)、図(関係が一目で分かる)、コード自体(動く仕様として最も正確)、口頭・ホワイトボード(速いが消える)。実務的な使い分けは、「変えにくいもの=文書と図で残す」「変えやすいもの=コードと口頭でよい」です。迷ったら、「半年後の自分が読んで分かるか」で判断してください。半年後の自分は、いまの文脈をほぼ忘れています。
なお、境界の表現方法として型システムを使う選択肢もあります。型が決まっていれば、境界の違反は実行前に検出できます(第2回で触れた「型を選ぶとは将来の壊れ方を選ぶこと」と同じ話です)。動的型の言語でも、境界部分だけ型注釈を付ける、スキーマを定義する(JSON Schema、Protocol Buffersなど)といった方法で、境界を機械的に検証できます。これは第7回で扱うCIともつながります。
📅 今後の展望:設計とAIとアーキテクチャテスト
設計の世界で起きている変化を2つ挙げます。第一に、設計を機械的に検証するという流れです。たとえば「AモジュールはBモジュールを参照してはいけない」という設計上の約束を、テストコードとして書いて自動実行する手法があります(ArchUnitなどのツール群が代表例です)。人間のレビューでは見落としやすい依存関係の違反を、CIで機械的に止められます。第1回で扱った「失敗を安い場所で見つける」の、設計版と言えます。
第二に、設計判断そのものをAIが支援する流れです。既存コードから構造を読み取り、変更の影響範囲を提示する、境界の候補を提案する、といった支援が現実的になっています。ただし、「何が変えにくいか」の判断は、組織や事業の事情に依存します。同じデータでも、来年廃止されるサービスなら変えやすく、10年使う基盤なら変えにくい。この判断に必要な文脈(この機能はいつまで使うのか、誰が依存するのか)は、人間の側が持つ情報です。AIが提案した構造を採用するかどうかの判断は、引き続き人間の仕事になると考えられます。
さらに、AIに実装を任せる場合、境界の設計はAIへの指示そのものになります。「この入力をこの形で受け取り、この形で返し、この場合はエラーとする」——これを決めておけば、AIの出力の正しさを機械的に検証できます。逆に境界が曖昧なままAIに任せると、検証できないコードが出てきます。第2回の「受け入れ条件」と今回の「境界」は、AI時代の開発で最も費用対効果の高い2つの成果物になっていくと考えられます。
まとめ
この記事を読んだあなたは、次に実装を始める前に、「これは柱か、壁紙か」と自問するようになります。そして、柱(データの形・境界・外部との約束)だけを先に決め、壁紙(名前・書き方・細部)は実装中に決めるという判断ができるようになります。
設計は、立派な書類を作ることではありません。後から変えると高くつくものを、変える前に決めておくことです。そのために必要なのは、完璧な図や長い文書ではなく、4つの問いと3行のメモです。実装の前に10分使う。それだけで、半年後のあなたとチームが救われます。
第4回では、関門4の「実装」に踏み込み、変更を記録する技術であるGitを扱います。コミットとプルリクエストをどう刻むと、レビューが速くなり、後から原因を追えるのか——「コミットは未来の自分への手紙」という視点で掘ります。
参考文献
- David L. Parnas, “On the Criteria To Be Decomposed into Modules”, Communications of the ACM, Vol.15, No.12, 1972(情報隠蔽の原典) — https://dl.acm.org/doi/10.1145/361598.361623
- Martin Fowler, “Refactoring: Improving the Design of Existing Code” (2nd ed.), Addison-Wesley, 2018 — https://martinfowler.com/books/refactoring.html
- Eric Evans, “Domain-Driven Design: Tackling Complexity in the Heart of Software”, Addison-Wesley, 2003(境界とユビキタス言語) — https://www.domainlanguage.com/
- Robert C. Martin, “Clean Architecture: A Craftsman’s Guide to Software Structure and Design”, Prentice Hall, 2017(依存関係の方向) — https://www.oreilly.com/
- John Ousterhout, “A Philosophy of Software Design” (2nd ed.), Yaknyam Press, 2021(複雑さの設計) — https://web.stanford.edu/~ouster/cgi-bin/book.php
- Michael Nygard, “Documenting Architecture Decisions”, 2011(ADRの原典) — https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions
- ISO/IEC/IEEE 42010:2022, “Software, systems and enterprise — Architecture description”(アーキテクチャ記述の標準) — https://www.iso.org/standard/74393.html
- Simon Brown, “The C4 model for visualising software architecture”(図の使い分け) — https://c4model.com/
- Melvin E. Conway, “How Do Committees Invent?”, Datamation, 1968(コンウェイの法則) — https://www.melconway.com/Home/Committees_Paper.html
- Google, “Design Docs at Google”(実装前の設計レビュー文化) — https://www.industrialempathy.com/posts/design-docs-at-google/
- Ron Jeffries, “Extreme Programming Installed”, Addison-Wesley, 2001(YAGNIとrule of threeの背景) — https://ronjeffries.com/
- Python Software Foundation, “PEP 373: Python 2.7 Release Schedule”(Python 2サポート終了の予告) — https://peps.python.org/pep-0373/
- Python Software Foundation, “Python 3.0 Release”(2008年12月3日リリース) — https://www.python.org/downloads/release/python-300/
- Python Software Foundation, “PEP 404: Python 2.8 Un-release Schedule”(2.8を作らないという決定) — https://peps.python.org/pep-0404/
- ArchUnit, “ArchUnit User Guide”(設計上の約束をテストで検証する) — https://www.archunit.org/
- Thoughtworks, “Technology Radar”(設計・アーキテクチャ検証の動向) — https://www.thoughtworks.com/radar
Rui Software