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;
EOFStep 2: 機能を安全に追記
bash
claudesrc/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: 機能追加の安全性確認
TaskManager に tags 機能を追加させせよ。
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 のラウンドトリップが正確に機能すること
