導入
Template Methodは「処理の骨組みを親が決め、一部の手順だけ子に任せる」。Iteratorは「コレクションの内部構造を隠して、要素を順に取り出す」——C#のforeachとyieldがその実装です。
図解
flowchart TB
T["親: Cook() の手順<br/>①下ごしらえ → ②焼く(子が実装) → ③盛り付け"] --> C1["カレー: 焼く=煮込む"]
T --> C2["ステーキ: 焼く=グリル"]
サンプル
// Template Method: 手順の骨組みは親、可変部分だけ子が override
new CurryRecipe().Cook();
// 下ごしらえ / 具材を煮込む / 盛り付け
// Iterator: yield で「順に返す」処理を書ける(内部構造を隠す)
foreach (int n in Countdown(3))
Console.WriteLine(n); // 3 / 2 / 1
IEnumerable<int> Countdown(int from)
{
for (int i = from; i >= 1; i--)
yield return i; // 呼ばれるたびに次の値を返す
}
abstract class Recipe
{
public void Cook() // テンプレート(骨組みは固定)
{
Console.WriteLine("下ごしらえ");
MainStep(); // 可変部分は子に委ねる
Console.WriteLine("盛り付け");
}
protected abstract void MainStep();
}
class CurryRecipe : Recipe
{
protected override void MainStep() => Console.WriteLine("具材を煮込む");
}
- Template Method: 全体の手順は親が固定し、一部のステップだけ子に
overrideさせる - Iterator:
yield returnで「要素を順に返す」列挙を実装し、内部構造を隠す foreachが使えるコレクションはIteratorパターンを実装している
演習
foreach (int n in EvenNumbers(6))
Console.Write($"{n} "); // 2 4 6
// TODO: 2 から max までの偶数を yield return で順に返す EvenNumbers を定義してください
___
- 期待される出力:
2 4 6
ヒント1を見る
IEnumerable<int> EvenNumbers(int max) { for (int i = 2; i <= max; i += 2) yield return i; }
ヒント2を見る
yield returnで1つずつ返すとforeachで列挙できます
まとめ
- Template Methodは手順の骨組みを親、可変部を子に委ねる
- Iteratorは内部構造を隠して要素を順に返す(
yield) foreachはIteratorパターンの上に成り立つ
次回: 残る3パターンVisitor/Interpreter/Mementoです。