本文へスキップ
BecomeCoder

C#デザインパターンコース · 第1章 デザインパターン · レッスン11

振る舞い④:Template Method / Iterator

ブラウザで完結

導入

Template Methodは「処理の骨組みを親が決め、一部の手順だけ子に任せる」。Iteratorは「コレクションの内部構造を隠して、要素を順に取り出す」——C#のforeachとyieldがその実装です。

図解

flowchart TB
    T["親: Cook() の手順<br/>①下ごしらえ → ②焼く(子が実装) → ③盛り付け"] --> C1["カレー: 焼く=煮込む"]
    T --> C2["ステーキ: 焼く=グリル"]

サンプル

Template Methodは「骨組みの親ファイル」と「可変部の子ファイル」に分かれます。IteratorはyieldなのでProgram.csの中で書きます。

1. 骨組み(Recipe.cs)。手順の順番はここで固定します。子クラスは順番を変えられません。

// Template Method: 手順の骨組みは親、可変部分だけ子が override
public abstract class Recipe
{
    public void Cook()          // テンプレート(骨組みは固定)
    {
        Console.WriteLine("下ごしらえ");
        MainStep();             // 可変部分は子に委ねる
        Console.WriteLine("盛り付け");
    }

    protected abstract void MainStep();
}

2. 可変部だけを埋める子(CurryRecipe.cs)。レシピを増やすときはファイルを1つ足すだけです。

public class CurryRecipe : Recipe
{
    protected override void MainStep() => Console.WriteLine("具材を煮込む");
}

3. 使う側とIterator(Program.cs)。yield returnは「呼ばれるたびに次の値を返す」書き方です。

new CurryRecipe().Cook();
// 下ごしらえ / 具材を煮込む / 盛り付け

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;     // 呼ばれるたびに次の値を返す
}
  • 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です。

実際に動かしてみよう

このレッスンのサンプルは、実務と同じように役割ごとの .cs ファイルへ分けてあります。下のエディタは最初からその複数ファイルが入った状態で、上のタブでファイルを切り替えられます。そのまま「▶ 実行」を押せば全ファイルをまとめてコンパイルして動かせるので、クラスを足したりファイルをまたいで書き換えたりしながら進めましょう(演習は本文のコードをコピーして Program.cs のタブに貼り付ければ試せます)。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。

次のレッスンへ →