Dev Study
← 解説「作業を小さく分解する — 動く状態を保ちながら進む」に戻る

サンプルコードで身につける: 作業を小さく分解する — 動く状態を保ちながら進む

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1分解する前と後の比較

「お気に入り機能を作る」のままでは、どこから手を付けるかも、いつ終わったかも判断できません。確認できる単位まで割ると、着手する順番と完了の基準がはっきりします。

// ── 分解前(着手できない)──
// TODO: お気に入り機能を作る
//   → 何から始める? どうなったら終わり? が答えられない

// ── 分解後(上から順に着手できる)──
// TODO(1): カードに☆ボタンを置く
// TODO(2): クリックで☆/★を切り替える
// TODO(3): ★の項目だけをお気に入り一覧に出す
// TODO(4): サーバーに保存してリロード後も残す
//   → どのステップも「画面を見れば終わったか分かる」

2ステップ①: まずボタンを置くだけ

最初のステップは「押しても何も起きない☆ボタンを表示する」だけです。物足りなく感じますが、画面に☆が出た時点でこのステップは完了で、アプリは動く状態のままです。

import { Component } from '@angular/core';

@Component({
  selector: 'app-favorite-button',
  // まだクリック処理はない。表示されればステップ①は完了
  template: '<button>☆</button>',
})
export class FavoriteButton {}

// 「未完成の機能」ではなく「完了した1ステップ」と考える。
// この時点でコミットしてよい

3ステップ②: クリックで切り替える

次のステップで初めてクリック処理を足します。ステップ①が動いていたので、もしここで壊れたら疑うのは今回足した数行だけです。この安心感が分解の効果です。

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-favorite-button',
  // ステップ②で追加: クリックで表示を切り替える
  template: '<button (click)="toggle()">{{ isFavorite() ? "★" : "☆" }}</button>',
})
export class FavoriteButton {
  isFavorite = signal(false);

  toggle() {
    this.isFavorite.update((v) => !v);
  }
}
// 壊れたら疑うのは「今回足した部分」だけでよい

4粒度の目安 — 大きすぎ・小さすぎの判断

1ステップは「終わったら画面で確かめられて、数十分から半日で終わる」大きさが目安です。確認方法が言えないステップは大きすぎ、確認する意味がない単位は小さすぎです。

// ── 粒度の判断基準 ──
//
// 大きすぎる例:
//   「お気に入り機能を完成させる」
//   → 終わったかどうかを画面で一言で確認できない
//
// ちょうどよい例:
//   「クリックで☆/★が切り替わるようにする」
//   → 確認方法が明確(押して表示が変わればOK)
//
// 小さすぎる例:
//   「変数名を1つ決める」
//   → 単独で確認する意味がない。上のステップに含める
//
// 迷ったら「このステップの確認方法を一言で言えるか」で判断する

5分解したステップはコミットの単位になる

ステップを1つ終えるごとにコミットすると、履歴が作業の記録そのものになります。途中で方針を変えたくなっても、どのステップまで戻ればよいかが履歴から読み取れます。

# ステップごとにコミットした履歴(git log --oneline の出力例)
git log --oneline
# f4d2a10 feat: お気に入りをサーバーに保存する      ← ステップ④
# 9c81b3e feat: お気に入り一覧ページに反映          ← ステップ③
# 5e7f042 feat: クリックで☆/★を切り替える          ← ステップ②
# 1a3c9d8 feat: カードにお気に入りボタンを配置      ← ステップ①

# 履歴 = 作業の分解がそのまま残った記録。
# 「②までは正しかった」のように戻る位置も判断できる