C#入門(第18回)

前回振り返り

Template Method パターン

Template Methodパターンとは、処理の共通部分を抽象クラスに抽出し、固有の処理を具象クラスで実装する手法です。異なる色のペンや、筆・クレヨンなどを用いても同じ形の文字になるように、スーパークラスで処理の枠組みを決め、サブクラスで具体的な内容を定めるデザインパターンと呼ばれます。

Template Methodパターンでは、抽象クラスに共通の処理を実装し、派生クラスに個別の処理を実装させることで、アルゴリズムの構造を変えずに処理の流れをカスタマイズできます。以下は、Template Methodパターンの使い方の例です。

  1. 抽象クラスを作成する。
  2. 抽象クラスに共通の処理を実装する。
  3. 抽象メソッドを定義する。
  4. 具象クラスを作成する。
  5. 抽象メソッドをオーバーライドして、個別の処理を実装する。
Template Method パターンのクラス図

前回演習問題の解答 例

問題1

問題文

Template Method パターン を作成してみましょう。

wikipedia のJava実装例をC#で記述してみましょう。


解答例

abstract class StringLister
{
    protected abstract string formatHeader();
    protected abstract string formatItem(string item);
    protected abstract string formatFooter();
    public string display(string[] items)
    {
        StringBuilder result = new (this.formatHeader());
        foreach (string item in items)
        {
            result.Append(this.formatItem(item));
        }
        result.Append(this.formatFooter());
        return result.ToString();
    }
}

class PlainTextStringLister : StringLister
{
    protected override String formatHeader()
    {
        return "";
    }
    protected override String formatItem(String item)
    {
        return " - " + item + "\r\n";
    }
    protected override String formatFooter()
    {
        return "";
    }
}

class HtmlStringLister : StringLister
{
    protected override String formatHeader()
    {
        return "<ul>\r\n";
    }
    protected override String formatItem(String item)
    {
        return "  <li>" + item + "</li>\r\n";
    }
    protected override String formatFooter()
    {
        return "<ul>\r\n";
    }
}

public class TemplateMethodTest
{
    public static void Main(String[] argv)
    {
        String[] items = { "First", "Second", "Third" };
        StringLister l1 = new PlainTextStringLister();
        StringLister l2 = new HtmlStringLister();
        Console.WriteLine(l1.display(items));
        Console.WriteLine(l2.display(items));

    }
}

問題2

問題文

問1のクラスを身近なものにアレンジしてみましょう。


解答例

class CSVTextStringLister : StringLister
{
    protected override String formatHeader()
    {
        return "";
    }
    protected override String formatItem(String item)
    {
        return item + ",";
    }
    protected override String formatFooter()
    {
        return "";
    }
}

public class TemplateMethodTest
{
    public static void Main(String[] argv)
    {
        String[] items = { "First", "Second", "Third" };
        StringLister l1 = new PlainTextStringLister();
        StringLister l2 = new HtmlStringLister();
        StringLister l3 = new CSVTextStringLister();
        Console.WriteLine(l1.display(items));
        Console.WriteLine(l2.display(items));
        Console.WriteLine(l3.display(items));

        if (l3.display(items).EndsWith(","))
        {
            String str = l3.display(items).Substring(0, l3.display(items).Length - 1);
            Console.WriteLine(str);
        }
    }
}

クラスとして、CSVTextStringListerを追加しているが、最終Itemの後のカンマを取り除きたい場合もStringListerクラスは改修すべきではない。


今回の演習問題

問題1

問題文

Composite パターンを作成してみましょう。

wikipedia のJava実装例をC#で記述してみましょう。

問題2

問題文

問1のクラスを身近なものにアレンジしてみましょう。

コメント