06 開発手法カタログ — プロジェクトタイプ別レシピ
どの開発手法をどのプロジェクトで使うかを整理する「手法セレクタ」
手法選択ガイド
新しいプロジェクトが来た
↓
どんな性質のプロジェクト?
│
├── ビジネスロジック重要・長期運用
│ └── → DDD + クリーンアーキテクチャ
│
├── 外部APIやDBを触る機能
│ └── → TDD(テストファースト)
│
├── 要件が曖昧・ステークホルダーとの合意が必要
│ └── → BDD(振舞駆動)
│
├── APIを設計・公開する
│ └── → 仕様駆動開発(OpenAPI先行)
│
└── スクリプト・ワンショットツール
└── → シンプル実装(手法不要)
TDD — テスト駆動開発
いつ使う: 外部API・DB・副作用を伴う機能
Red-Green-Refactorサイクル
1. Red: 失敗するテストを書く
2. Green: テストを通す最小実装をする
3. Refactor: コードをきれいにする(テストはまだ通る)
→ 繰り返す
実例
# Step 1: Red(失敗するテスト)
def test_validate_email():
assert validate_email("user@example.com") == True
assert validate_email("invalid") == False
# → ImportError: cannot import name 'validate_email'
# Step 2: Green(通す最小実装)
def validate_email(email: str) -> bool:
return "@" in email # 最小実装
# Step 3: Refactor(改善)
import re
def validate_email(email: str) -> bool:
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
BDD — 振舞駆動開発
いつ使う: ステークホルダーとの要件合意・受け入れテスト
Given-When-Then形式
Feature: ユーザーログイン
Scenario: 正常なログイン
Given ユーザー "alice@example.com" が登録済みである
When パスワード "correct-password" でログインする
Then ダッシュボードにリダイレクトされる
Scenario: 誤ったパスワード
Given ユーザー "alice@example.com" が登録済みである
When パスワード "wrong-password" でログインする
Then "認証エラー" のメッセージが表示される
メリット
- 非エンジニアでも読める仕様書
- テストと仕様書が同一ドキュメント
- 要件の抜け漏れを防げる
DDD — ドメイン駆動設計
いつ使う: ビジネスロジックが複雑で長期運用するシステム
主要概念
| 概念 | 説明 | 例 |
|---|---|---|
| エンティティ | IDを持つオブジェクト | User(id=123) |
| 値オブジェクト | 値が同じなら同一 | Email("a@b.com") |
| 集約 | 整合性の境界 | Order + OrderItems |
| リポジトリ | 永続化の抽象 | UserRepository |
| ドメインサービス | オブジェクトをまたがるロジック | TransferService |
レイヤー構造
Presentation (API/UI)
↓
Application (ユースケース)
↓
Domain (ビジネスロジック) ← ここが核心
↓
Infrastructure (DB/外部API)
仕様駆動開発 — OpenAPI先行設計
いつ使う: APIを設計・公開するプロジェクト
手順
1. OpenAPI仕様を書く(コードを書く前に)
↓
2. モックサーバーでフロントエンドが開発開始
↓
3. 仕様からサーバーコードを生成
↓
4. 仕様に合わせてテストを自動生成
↓
5. 仕様・テスト・実装が常に同期
# openapi.yaml(先に書く)
paths:
/users/{id}:
get:
summary: ユーザー取得
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/User'
クリーンアーキテクチャ
いつ使う: 長期運用・チーム開発・依存関係を整理したい場合
依存の方向
外側 → 内側に依存(内側は外側を知らない)
Frameworks & Drivers (最外層)
→ Interface Adapters
→ Use Cases
→ Entities (最内層・純粋なビジネスロジック)
実装例(Python)
# Domain Layer(外部依存ゼロ)
class User:
def __init__(self, id: int, email: str):
self.id = id
self.email = email
# Use Case Layer(Repositoryは抽象に依存)
class GetUserUseCase:
def __init__(self, user_repo: UserRepository):
self._repo = user_repo
def execute(self, user_id: int) -> User:
return self._repo.find_by_id(user_id)
# Infrastructure Layer(DBの実装はここだけ)
class PostgresUserRepository(UserRepository):
def find_by_id(self, user_id: int) -> User:
# PostgreSQL固有のコード
...
SOLID原則
| 原則 | 意味 | 実践 |
|---|---|---|
| S: 単一責任 | クラスは1つの責任を持つ | UserValidator と UserSaver を分ける |
| O: 開放/閉鎖 | 拡張に開いて修正に閉じる | 継承より合成を使う |
| L: リスコフ置換 | サブクラスは基底クラスと置換可能 | インターフェースを守る |
| I: インターフェース分離 | 大きなIFより小さなIFを複数 | 必要なメソッドだけ定義 |
| D: 依存逆転 | 具体でなく抽象に依存する | DIコンテナ・Repository pattern |
SSOTでの手法管理
各手法の詳細をSSOTに格納:
00_SYSTEM/開発手法カタログ/
├── 00_セレクタ.md ← このファイルが出発点
├── 01_TDD.md
├── 02_BDD.md
├── 03_DDD.md
├── 04_仕様駆動開発.md
└── 05_クリーンアーキテクチャ.md
新しいプロジェクト開始時は 00_セレクタ.md から始める。