Skip to content

Lesson 5: コードの追記と修正

クラス: 初級
所要時間: 約35分
前提知識: 初級 Lesson 1〜4 完了済み


1. 解説

「追記」と「修正」の違い

操作説明指示の例
追記(Add)既存コードを壊さず新しい機能を追加「〜関数を追加せよ」
修正(Fix)既存の動作を変更・改善「〜関数の〇〇を変えせよ」
リプレース既存の実装を別の実装に置き換え「〜を使って書き直せよ」

既存コードを壊さない追記のコツ

bash
# ❌ 曖昧な指示(既存コードが壊れる可能性)
「app.js に認証を追加してください」

# ✅ 範囲を限定した指示
「app.js の既存の関数は変更せず、
 validateToken(token) 関数だけを新たに追加してください」

安全な修正の流れ

1. 変更前に確認
   「この変更で影響を受ける他の関数はありますか?」

2. 変更内容の提示を求める
   「実際に変更する前に、変更内容を説明してください」

3. 承認してから適用
   「問題ないので適用してください」

4. 変更後の動作確認
   「変更後にテストを実行してください」

2. 実践

Step 1: ベースコードを用意

bash
mkdir -p ~/claude-practice/elementary/lesson5/src
cd ~/claude-practice/elementary/lesson5

cat > src/taskManager.js << 'EOF'
class TaskManager {
  constructor() {
    this.tasks = [];
    this.nextId = 1;
  }

  addTask(title, priority = 'medium') {
    const task = {
      id: this.nextId++,
      title,
      priority,
      completed: false,
      createdAt: new Date().toISOString(),
    };
    this.tasks.push(task);
    return task;
  }

  getTask(id) {
    return this.tasks.find(t => t.id === id) || null;
  }

  listTasks() {
    return [...this.tasks];
  }

  completeTask(id) {
    const task = this.getTask(id);
    if (!task) throw new Error(`Task ${id} not found`);
    task.completed = true;
    return task;
  }
}

module.exports = TaskManager;
EOF

Step 2: 機能を安全に追記

bash
claude
src/taskManager.js を読んでください。
既存のメソッドを変更せずに、以下のメソッドを追加してください:

- deleteTask(id): タスクを削除(見つからなければ Error)
- updateTask(id, { title, priority }): 部分更新
- getByPriority(priority): 優先度で絞り込み
- getStats(): { total, completed, pending } を返す

Step 3: 既存メソッドの修正

addTask メソッドを修正してください:
- dueDate パラメータを追加(省略可能、ISO形式の文字列)
- priority は 'low' | 'medium' | 'high' のみ許可。それ以外は Error

変更前に確認:

修正によって既存の addTask の呼び出し方に影響はありますか?
変更内容を説明してから適用してください。

Step 4: 後方互換性を保ちながら変更

listTasks メソッドに以下のオプション引数を追加してください。
既存の listTasks() の呼び出し(引数なし)は今まで通り動作すること:

listTasks({ completed, priority, sortBy } = {}) の形に変更
- completed: true/false でフィルタリング
- priority: 'low'|'medium'|'high' でフィルタリング
- sortBy: 'createdAt'|'priority'|'dueDate' でソート

Step 5: 変更の動作確認

bash
node -e "
const TaskManager = require('./src/taskManager');
const tm = new TaskManager();
tm.addTask('Buy groceries', 'high');
tm.addTask('Do laundry', 'low');
tm.addTask('Send email', 'medium');
tm.completeTask(1);
console.log('Stats:', JSON.stringify(tm.getStats()));
console.log('High priority:', JSON.stringify(tm.getByPriority('high')));
console.log('Pending:', JSON.stringify(tm.listTasks({ completed: false })));
"

3. 確認課題(Assignment)

課題 5-1: 機能追加の安全性確認

TaskManagertags 機能を追加させせよ。

TaskManager に以下の機能を追加してください。
既存のテストやインターフェースを壊さないこと:

1. addTask に tags 配列を追加(省略時は空配列)
2. addTag(id, tag): 既存タスクにタグを追加
3. removeTag(id, tag): タスクからタグを削除
4. getByTag(tag): タグでタスクを絞り込み

追加後:

bash
node -e "
const TaskManager = require('./src/taskManager');
const tm = new TaskManager();
const t = tm.addTask('Review PR');  // tags なしで作成できるか確認
console.log('No tags:', t.tags);
"

達成条件: 既存の引数なしの呼び出しが壊れないこと

課題 5-2: バリデーション強化

addTask の priority バリデーションを強化してください:
- 数値が渡された場合: 1=low, 2=medium, 3=high に変換
- 大文字小文字を区別しない: 'HIGH' → 'high'
- 無効な値: TypeError ではなく ValidationError をスロー

達成条件: addTask('test', 'HIGH') が正常動作し、addTask('test', 'invalid') が ValidationError をスローすること

課題 5-3: 段階的な機能追加

以下を3回の別々の指示に分けて実行せよ(一度に全部指示しない):

1回目: 「exportToJSON() メソッドを追加せよ」
→ 動作確認してから
2回目: 「importFromJSON(jsonString) メソッドを追加せよ」
→ 動作確認してから
3回目: 「exportしてimportしたとき、全タスクが完全に復元されるかテストコードを書いせよ」

達成条件: export→import のラウンドトリップが正確に機能すること


自己チェックリスト


次の型

Lesson 6: 複数ファイルの関係把握 →

Claude Code Dojo