デザインパターン入門

Abstract Factoryパターン

関連する部品を組み合わせて製品を作る.

どんな場合に使うのか

部品の具体的な実装には注目せず,インターフェース(API)に注目する.そして,そのインターフェース(API)だけを使って,部品を組み立て,製品にまとめる.

クラス図

ポイント

  • 具体的な工場を新たに追加するのは簡単.部品を新たに追加するのは困難.

具体的な工場:ListFactoryクラス

  • プログラムによっては,ここでnewするのではなく,Prototypeパターンをつかってcloneを行う場合もあるかも.

具体的な部品:ListTrayクラス

  • ここで変数itemの中身が実際に何なのかを調べて,switch文やif文を使うようなプログラムを書いてはいけません.

サンプルプログラム

// Program.cs
using System;
using factory;

namespace chap08 {
  class Program {
    static void Main(string[] args) {
      Console.Write("li(0) or td(1)?:");
      String line = Console.ReadLine();
      String classname = ""; String assembly = "";
      if (line[0] == '0') {
        assembly = "listfactory.dll";
        classname = "listfactory.ListFactory";
      } else {
        assembly = "tablefactory.dll";
        classname = "tablefactory.TableFactory";
      }

      Factory factory = Factory.getFactory(assembly, classname);

      Link asahi = factory.createLink("朝日新聞", "http://www.asahi.com/");
      Link yomiuri = factory.createLink("読売新聞", "http://www.yomiuri.co.jp/");

      Tray traynews = factory.createTray("新聞");
      traynews.add(asahi);
      traynews.add(yomiuri);

      Page page = factory.createPage("Linkpage", "yamanobori_old");
      page.add(traynews);
      page.output();
      Console.Read();
    }
  }
}

// Factory.cs
using System;
using System.Reflection;

namespace factory {
  public abstract class Factory {
    public static Factory getFactory(String assembly,String classname) {
      Factory factory = null;
      try {
        Assembly asm = Assembly.LoadFrom(assembly);
        factory = (Factory)asm.CreateInstance(classname, true);
      } catch (Exception e) {
        Console.Write(e);
      }
      return factory;
    }
    public abstract Link createLink(String caption, String url);
    public abstract Tray createTray(String caption);
    public abstract Page createPage(String title, String author);
  }
}

// Item.cs
using System;

namespace factory {
  public abstract class Item {
    protected String caption;
    public Item(String caption) {
      this.caption = caption;
    }
    public abstract String makeHTML();
  }
}

// Link.cs
using System;

namespace factory {
  public abstract class Link : Item {
    protected String url;
    public Link(String caption, String url)
      : base(caption) {
      this.url = url;
    }
  }
}

// Page.cs
using System;
using System.Collections;

namespace factory {
  public abstract class Page {
    protected String title;
    protected String author;
    protected ArrayList content = new ArrayList();
    public Page(String title, String author) {
      this.title = title;
      this.author = author;
    }
    public void add(Item item) {
      content.Add(item);
    }
    public void output() {
      String output = this.makeHTML();
      Console.Write(output);
      Console.WriteLine(title + ".html" + "を作成しました.");
    }
    public abstract String makeHTML();
  }
}

// Tray.cs
using System;
using System.Collections;

namespace factory {
  public abstract class Tray : Item {
    protected ArrayList tray = new ArrayList();
    public Tray(String caption) : base(caption) { }
    public void add(Item item) {
      tray.Add(item);
    }
  }
}

// ListFactory.cs
using factory;

namespace listfactory {
  public class ListFactory : Factory {
    public override Link createLink(string caption, string url) {
      return new ListLink(caption, url);
    }
    public override Tray createTray(string caption) {
      return new ListTray(caption);
    }
    public override Page createPage(string title, string author) {
      return new ListPage(title, author);
    }
  }
}

// ListLink.cs
using System;
using factory;

namespace listfactory {
  public class ListLink : Link {
    public ListLink(String caption, String url) : base(caption, url) { }

    public override string makeHTML() {
      return "  <li><a href=\"" + url + "\">" + caption + "</a></li>\n";
    }
  }
}

// ListPage.cs
using System;
using System.Text;
using factory;

namespace listfactory {
  public class ListPage : Page {
    public ListPage(String title, String author) : base(title, author) { }

    public override string makeHTML() {
      StringBuilder buffer = new StringBuilder();
      buffer.AppendLine("<html><head><title>" + title + "</title></head>");
      buffer.AppendLine("<body>");
      buffer.AppendLine("<h1>" + title + "</h1>");
      buffer.AppendLine("<ul>");
      foreach (Item item in content) {
        buffer.Append(item.makeHTML());
      }
      buffer.AppendLine("</ul>");
      buffer.AppendLine("<hr><address>" + author + "</address>");
      buffer.AppendLine("</body></html>");

      return buffer.ToString();
    }
  }
}

// ListTray.cs
using System;
using System.Text;
using factory;

namespace listfactory {
  public class ListTray : Tray {
    public ListTray(String caption) : base(caption) { }

    public override string makeHTML() {
      StringBuilder buffer = new StringBuilder();
      buffer.AppendLine("<li>");
      buffer.AppendLine(caption);
      buffer.AppendLine("<ul>");
      foreach (Item item in tray) {
        buffer.Append(item.makeHTML());
      }
      buffer.AppendLine("</ul>");
      buffer.AppendLine("</li>");

      return buffer.ToString();
    }
  }
}

// TableFactory.cs
using factory;

namespace tablefactory {
  public class TableFactory : Factory {
    public override Link createLink(string caption, string url) {
      return new TableLink(caption, url);
    }
    public override Tray createTray(string caption) {
      return new TableTray(caption);
    }
    public override Page createPage(string title, string author) {
      return new TablePage(title, author);
    }
  }
}

// TableLink.cs
using System;
using factory;

namespace tablefactory {
  public class TableLink : Link {
    public TableLink(String caption, String url) : base(caption, url) { }

    public override string makeHTML() {
      return "<td><a href=\"" + url + "\">" + caption + "</a></td>\n";
    }
  }
}

// TablePage.cs
using System;
using System.Text;
using factory;

namespace tablefactory {
  public class TablePage : Page {
    public TablePage(String title, String author) : base(title, author) { }

    public override string makeHTML() {
      StringBuilder buffer = new StringBuilder();
      buffer.AppendLine("<html><head><title>" + title + "</title></head>");
      buffer.AppendLine("<body>");
      buffer.AppendLine("<h1>" + title + "</h1>");

      buffer.AppendLine("<table width=\"80%\" border=\"3\".");
      foreach (Item item in content) {
        buffer.Append("<tr>" + item.makeHTML() + "</tr>");
      }
      buffer.AppendLine("</table>");
      buffer.AppendLine("<hr><address>" + author + "</address>");
      buffer.AppendLine("</body></html>");

      return buffer.ToString();
    }
  }
}

// TableTray.cs
using System;
using System.Text;
using factory;

namespace tablefactory {
  public class TableTray : Tray {
    public TableTray(String caption) : base(caption) { }

    public override string makeHTML() {
      StringBuilder buffer = new StringBuilder();
      buffer.AppendLine("<td>");
      buffer.AppendLine("<table width=\"100%\" border=\"1\"><tr>");
      buffer.AppendLine("<td bgcollor=\"#cccccc\" align=\"center\" colspan=\"" + tray.Count + "\"><b>" + caption + "</b></td>");
      buffer.AppendLine("</tr>");
      buffer.AppendLine("<tr>");
      foreach (Item item in tray) {
        buffer.Append(item.makeHTML());
      }
      buffer.AppendLine("</tr>");
      buffer.AppendLine("</table></td>");

      return buffer.ToString();
    }
  }
}
||=
デザインパターン入門

このページへのコメント

7Fjmps Really appreciate you sharing this blog article.Much thanks again. Really Cool.

0
Posted by check this out 2013年12月21日(土) 14:23:41 返信

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

管理人/副管理人のみ編集できます