Skip to content

設計思考とコードレビュー

ジュニアが「答え」を競うのに対し、シニアは「問い」を設計する。この決定的な違いが、本ガイドの核心です。とりわけ、コードレビューを単なる「検品作業」から、チームの「設計力向上イベント」へと昇華させる視点は、技術組織の**レジリエンス(回復力)**を育む源泉となります。以下、判断を共有し、育てるための極意を整理します。


設計思考:意思決定の「解像度」を上げる

Section titled “設計思考:意思決定の「解像度」を上げる”

シニアの仕事は、複雑な問題を「解ける単位」に分解し、チームが進むべき道を照らすことです。

ジュニア・ミドルのアプローチ:

  • 「これが正しい」
  • 1つの解決策を提示
  • 他の選択肢を考慮しない

シニアのアプローチ:

  • 「制約条件を踏まえると、この3案がある」
  • 複数の選択肢を提示
  • 各選択肢のトレードオフを説明

1. トレードオフの可視化:鉄の三角形を意識する

Section titled “1. トレードオフの可視化:鉄の三角形を意識する”

「完璧なコード」を追い求めるのではなく、常に**「Scope(範囲)」「Time(時間)」「Quality(品質)」**のバランスを可視化します。

「決めない」という高度な技術

Section titled “「決めない」という高度な技術”

情報不足のまま勘で決めるのは博打です。シニアは、あえて判断を遅らせる**遅延決定(Deferred Decision)**を戦略的に行い、変更可能な設計(リバーシブルな決断)を維持します。

## 設計判断: 開発速度 vs 安定性
### 選択肢1: 開発速度を優先
- **実装**: 既存のライブラリをそのまま使用
- **メリット**: 迅速な開発、短期間でのリリース
- **デメリット**: 技術的負債の蓄積、将来の変更が困難
- **適用**: MVP、プロトタイプ、短期プロジェクト
### 選択肢2: 安定性を優先
- **実装**: カスタム実装、包括的なテスト
- **メリット**: 高い品質、長期的な保守性
- **デメリット**: 開発時間の増加、コストの増加
- **適用**: 本番環境、長期運用が前提のシステム
### 選択肢3: バランス型
- **実装**: 重要な部分はカスタム、その他はライブラリ
- **メリット**: 開発速度と安定性のバランス
- **デメリット**: 判断が難しい、設計の複雑化
- **適用**: 中規模プロジェクト、段階的な開発

2. UNKNOWN(未知)の管理:リスクを「状態」に変える

Section titled “2. UNKNOWN(未知)の管理:リスクを「状態」に変える”

「何が分からないか」をリストアップすることで、恐怖を「タスク」に変える。この「UNKNOWN管理」こそが、不測の事態での炎上を防ぐ最強の防御です。

// UNKNOWNを状態として扱う
class DesignDecision {
status: 'decided' | 'unknown' | 'needs_research';
alternatives: Alternative[];
constraints: Constraint[];
risks: Risk[];
markAsUnknown(reason: string, researchPlan: string): void {
this.status = 'unknown';
this.unknownReason = reason;
this.researchPlan = researchPlan;
this.deadline = this.calculateDeadline();
}
}

コードレビュー:コードの裏側にある「設計意図」を問う

Section titled “コードレビュー:コードの裏側にある「設計意図」を問う”

シニアのレビューは、100行のコード修正よりも、**1つの「良質な問い」**を重視します。

シニアのレビューはここが違う

Section titled “シニアのレビューはここが違う”

ジュニア・ミドルのレビュー:

  • 文法・書き方の指摘
  • 「変数名をキャメルケースにしてください」
  • 「インデントを修正してください」

シニアのレビュー:

  • 設計意図・責務・将来影響を見る
  • 「この関数の責務は何ですか?単一責任の原則に違反していませんか?」
  • 「この設計は将来の変更に対応できますか?」
**レビューコメント:**
「命名が分かりづらいです。直してください」
**問題点:**
- 具体的な改善点が不明確
- なぜ修正が必要かが説明されていない
- 強制的な口調
**レビューコメント:**
「この名前だと責務が広く見えます。
将来、ユーザー情報の更新機能も入りそうですが、その想定はありますか?
もし単一の責務に絞るなら、`updateUserEmail`のような名前の方が明確かもしれません。
また、`updateUser`という名前だと、パスワード更新も含まれるように見えますが、
セキュリティ上の理由で分離する想定はありますか?」
**改善点:**
- 将来の影響を指摘
- 質問形式で判断を促す
- 代替案を提示
- 学習を促進

指摘を「ギフト(学び)」に変える

Section titled “指摘を「ギフト(学び)」に変える”

「命名の修正」を、単なる書き換え指示ではなく**「ドメイン知識の再定義」の機会に変える。この積み重ねが、チームのコードベースを美しくするだけでなく、メンバーの「脳内モデル」**をアップデートします。

  1. 人ではなく将来を見る

    • 個人の能力を指摘するのではなく、将来の影響を指摘する
  2. 修正ではなく判断を促す

    • 具体的な修正を強制するのではなく、判断を促す質問をする
  3. 強制ではなく選択肢を出す

    • 1つの正解を押し付けるのではなく、複数の選択肢を提示する

レビューで使える黄金フレーズ

Section titled “レビューで使える黄金フレーズ”

以下のフレーズは、いずれもエンジニアリングの本質(整合性・可用性・保守性)を突いています。思考の型として提示することで、相手の判断を促します。

フレーズ: 「ここ、どこまでを一貫性の単位として守りたいですか? 失敗した場合、どこまで戻せる前提でしょうか?」

フレーズ: 「これが二重実行された場合、 “安全に同じ結果になる”設計になっていますか?」

フレーズ: 「現時点で未確定なのはどこでしょうか? 今回は”決めない”選択肢もありそうですがどうですか?」

フレーズ: 「今は◯◯前提ですが、 もし◯◯が増えたらどこを触る想定ですか?」

フレーズ: 「障害時、誰が・どこを見て・どう判断しますか?」

これは**可観測性(Observability)の核心です。コードが動くことだけでなく、本番環境での「デバッグのしやすさ」までをレビュー対象に含めます。可観測性の3本柱はLogs(ログ)・Metrics(メトリクス)・Traces(トレース)**です。


レビュー・パラダイム:監視から「共創」へ

Section titled “レビュー・パラダイム:監視から「共創」へ”
観点ミドル(「修正」のレビュー)シニア(「対話」のレビュー)
関心事記法、ロジックの正しさ責務の境界、将来の拡張、運用負荷
スタンスエラーを見つけて指摘する共に「より良い判断」を探索する
成果物バグのないコード納得感のある設計判断と、育ったメンバー
時間軸「今、動くか」「1年後、壊さずに変更できるか」

## 設計レビュー: 論点の提示
### 論点1: トランザクション境界の設計
**背景:**
注文作成時に在庫減算と支払い処理を同一トランザクションで行うか?
**選択肢:**
1. **同一トランザクション**: データ整合性が高いが、外部API呼び出しが含まれる
2. **Saga パターン**: 分散トランザクションを避けるが、補償トランザクションが必要
3. **イベントソーシング**: イベントで状態を管理、高い拡張性
**推奨:**
Saga パターン(選択肢2)
- 理由: 外部API呼び出しを含むため、分散トランザクションは避けるべき
- トレードオフ: 補償トランザクションの実装が必要
### 論点2: キャッシュ戦略
**背景:**
商品情報のキャッシュをどのように実装するか?
**選択肢:**
1. **Redis**: 高性能だが、追加のインフラが必要
2. **メモリキャッシュ**: シンプルだが、スケーラビリティに制限
3. **CDN**: 静的コンテンツに有効だが、動的コンテンツには不向き
**推奨:**
Redis(選択肢1)
- 理由: スケーラビリティとパフォーマンスのバランス
- トレードオフ: コストと運用の複雑化

シニアエンジニアの真の価値は、コードの書き方を教えることではなく、リーダーがいなくなった後も「あの人ならこう考えるだろうな」という「思考の残像」をチームに残すことです。

レビューコメント一つひとつを、未来のチームへの手紙だと思って筆を置いてください。

正解を教えるのは親切ですが、考え方を教えるのは慈悲です。