ストーリー
要件分析のフレームワーク
Step-by-Stepアプローチ
// 要件分析の5段階プロセス
enum RequirementPhase {
CLARIFY = "1. 要件の明確化",
SCOPE = "2. スコープの決定",
ESTIMATE = "3. 規模の見積もり",
IDENTIFY_NFR = "4. 非機能要件の特定",
PRIORITIZE = "5. 優先順位付け",
}
// Phase 1: 要件を明確化する質問リスト
const CLARIFICATION_QUESTIONS = {
users: [
"ユーザーは誰か?",
"同時接続ユーザー数は?",
"地理的な分布は?",
],
features: [
"最も重要な機能は何か?",
"MVPに含める機能は?",
"将来的に必要な機能は?",
],
constraints: [
"予算の制約は?",
"技術的な制約は?",
"規制要件は?",
],
data: [
"扱うデータの種類と量は?",
"データの保持期間は?",
"データの一貫性要件は?",
],
};
規模の見積もり(Back-of-the-Envelope Estimation)
// 概算見積もりの例: SNSサービス
class ScaleEstimation {
// DAU(Daily Active Users)から始める
readonly dau = 10_000_000; // 1000万DAU
// 読み書き比率
readonly readWriteRatio = 10; // 読み10 : 書き1
// 1ユーザーあたりの1日の操作
readonly writesPerUser = 2; // 投稿
readonly readsPerUser = 20; // 閲覧
estimate() {
const totalWritesPerDay = this.dau * this.writesPerUser;
const totalReadsPerDay = this.dau * this.readsPerUser;
// QPS(Queries Per Second)
const writeQPS = Math.ceil(totalWritesPerDay / 86400); // ~231 QPS
const readQPS = Math.ceil(totalReadsPerDay / 86400); // ~2315 QPS
const peakWriteQPS = writeQPS * 3; // ピーク時は3倍
const peakReadQPS = readQPS * 3;
// ストレージ見積もり
const avgPostSize = 1024; // 1KB per post
const dailyStorage = totalWritesPerDay * avgPostSize; // ~19GB/day
const yearlyStorage = dailyStorage * 365; // ~7TB/year
return {
writeQPS, readQPS,
peakWriteQPS, peakReadQPS,
dailyStorage, yearlyStorage,
};
}
}
要件からアーキテクチャへの変換
アーキテクチャドライバー
要件の中で、アーキテクチャの選択に最も影響を与えるものをアーキテクチャドライバーと呼びます。
interface ArchitectureDriver {
requirement: string;
impact: 'high' | 'medium' | 'low';
architecturalDecision: string;
}
// 例: SNSのアーキテクチャドライバー
const SNS_DRIVERS: ArchitectureDriver[] = [
{
requirement: "1000万DAUをサポート",
impact: "high",
architecturalDecision: "水平スケーリング可能なマイクロサービス構成",
},
{
requirement: "フィードのリアルタイム更新",
impact: "high",
architecturalDecision: "Fan-outパターン + WebSocket",
},
{
requirement: "画像・動画のアップロード",
impact: "medium",
architecturalDecision: "オブジェクトストレージ + CDN",
},
{
requirement: "グローバル展開",
impact: "medium",
architecturalDecision: "マルチリージョンデプロイ",
},
];
設計判断の記録(ADR)
// Architecture Decision Record
interface ADR {
id: string;
title: string;
status: 'proposed' | 'accepted' | 'deprecated' | 'superseded';
context: string; // なぜこの判断が必要か
decision: string; // 何を選んだか
consequences: string; // 結果としてどうなるか
alternatives: string[]; // 他の選択肢は何だったか
}
const exampleADR: ADR = {
id: "ADR-001",
title: "フィード配信にFan-out on Writeパターンを採用",
status: "accepted",
context: "フォロワーへのフィード配信の遅延を最小化したい",
decision: "投稿時にフォロワー全員のフィードキャッシュに書き込む",
consequences: "書き込みコストは増えるが、読み取りが高速になる",
alternatives: [
"Fan-out on Read: 読み取り時にフォロー先の投稿を集約",
"ハイブリッド: フォロワー数で戦略を切り替え",
],
};
実践:要件から設計への変換プロセス
ビジネス要件
↓ 明確化 & 質問
機能要件 + 非機能要件
↓ 規模見積もり
アーキテクチャドライバー特定
↓ パターン選択
ハイレベルアーキテクチャ
↓ 詳細設計
コンポーネント設計 + API設計 + データモデル
↓ 検証
ADR作成 + レビュー + PoC
まとめ
| ポイント | 内容 |
|---|---|
| 要件分析が最初 | コードやDBの前に「何を」「どれくらい」を明確にする |
| 規模見積もり | DAUからQPS、ストレージを概算する |
| アーキテクチャドライバー | 設計を決定づける重要な要件を特定する |
| ADR | 設計判断とその理由を記録する |
チェックリスト
- 要件分析の5段階プロセスを理解した
- Back-of-the-Envelope Estimationの手法を把握した
- アーキテクチャドライバーの概念を理解した
- ADRの書き方を把握した
次のステップへ
次は「非機能要件の定量化」を学びます。可用性99.99%やp99レイテンシ200ms未満といった指標を、具体的にどう定義し測定するのかを掘り下げます。
推定読了時間: 25分