Abstract Factoryパターン

Abstract Factoryパターンでは、抽象的な工場が登場し、抽象的な部品を組み合わせて抽象的な製品を作ります。つまり、部品の具体的な実装には注目せず、インタフェース(API)に注目する。そして、そのインタフェース(API)だけを使って、部品を組み立て、製品にまとめるのです。

ソースファイルを置くディレクトリ:

—-Main.java
  |
  |-factory
  |     |-Factory.java
  |     |-Item.java
  |     |-Link.java
  |     |-Tray.java
  |     |-Page.java
  |
  |-listfactory
        |-ListFactory.java
        |-ListLink.java
        |-ListTray.java
        |-ListPage.java

抽象的な部品: Itemクラス

   1: package factory;

   2:  

   3: public abstract class Item {

   4:     protected String caption;

   5:     

   6:     public Item(String caption){

   7:         this.caption = caption;

   8:     }

   9:     

  10:     public abstract String makeHTML();

  11: }

抽象的な部品: Linkクラス

   1: package factory;

   2:  

   3: public abstract class Link extends Item{

   4:     protected String url;

   5:     

   6:     public Link(String caption, String url){

   7:         super(caption);

   8:         this.url = url;

   9:     }

  10: }

具体的な部品: ListLinkクラス

   1: package listfactory;

   2:  

   3: import factory.Link;

   4:  

   5: public class ListLink extends Link {

   6:  

   7:     public ListLink(String caption, String url) {

   8:         super(caption, url);

   9:     }

  10:  

  11:     @Override

  12:     public String makeHTML() {

  13:         return " <li><a href=\"" + url + "\">" + caption + "</a></li>\n";

  14:     }

  15:  

  16: }

抽象的な部品: Trayクラス

   1: package factory;

   2:  

   3: import java.util.ArrayList;

   4:  

   5: public abstract class Tray extends Item {

   6:     protected ArrayList<Object> tray = new ArrayList<Object>();

   7:     public Tray(String caption) {

   8:         super(caption);

   9:     }

  10:     

  11:     public void add(Item item){

  12:         tray.add(item);

  13:     }

  14: }

具体的な部品: ListTrayクラス

   1: package listfactory;

   2:  

   3: import java.util.Iterator;

   4:  

   5: import factory.Item;

   6: import factory.Tray;

   7:  

   8: public class ListTray extends Tray {

   9:  

  10:     public ListTray(String caption) {

  11:         super(caption);

  12:     }

  13:  

  14:     @Override

  15:     public String makeHTML() {

  16:         StringBuilder buffer = new StringBuilder();

  17:         buffer.append("<li>\n");

  18:         buffer.append(caption + "\n");

  19:         

  20:         buffer.append("<ul>\n");

  21:         

  22:         Iterator<Object> it = tray.iterator();

  23:         

  24:         while(it.hasNext()) {

  25:             Item item = (Item)it.next();

  26:             buffer.append(item.makeHTML());

  27:         }

  28:         

  29:         buffer.append("</ul>\n");

  30:         buffer.append("</li>\n");

  31:         

  32:         return buffer.toString();

  33:     }

  34:  

  35: }

抽象的な部品: Pageクラス

   1: package factory;

   2:  

   3: import java.io.FileWriter;

   4: import java.io.IOException;

   5: import java.io.Writer;

   6: import java.util.ArrayList;

   7:  

   8: public abstract class Page {

   9:     protected String title;

  10:     protected String author;

  11:     

  12:     protected ArrayList<Object> content = new ArrayList<Object>();

  13:     public Page(String title, String author) {

  14:         this.title = title;

  15:         this.author = author;

  16:     }

  17:     

  18:     public void add(Item item) {

  19:         content.add(item);

  20:     }

  21:     

  22:     public void output() {

  23:         try {

  24:             String filename = title + ".html";

  25:             Writer writer = new FileWriter(filename);

  26:             writer.write(this.makeHTML());

  27:             writer.close();

  28:             

  29:             System.out.println(filename + " を作成しました。");

  30:         } catch (IOException e) {

  31:             e.printStackTrace();

  32:         }

  33:     }

  34:     

  35:     public abstract String makeHTML();

  36: }

具体的な部品: ListPageクラス

   1: package listfactory;

   2:  

   3: import java.util.Iterator;

   4:  

   5: import factory.Item;

   6: import factory.Page;

   7:  

   8: public class ListPage extends Page {

   9:  

  10:     public ListPage(String title, String author) {

  11:         super(title, author);

  12:     }

  13:  

  14:     @Override

  15:     public String makeHTML() {

  16:         StringBuilder buffer = new StringBuilder();

  17:         buffer.append("<html><head>");

  18:         buffer.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");

  19:         buffer.append("<title>" + title + "</title></head>\n");

  20:         buffer.append("<body>\n");

  21:         buffer.append("<h1>" + title + "</h1>\n");

  22:         buffer.append("<ul>\n");

  23:         

  24:         Iterator<Object> it = content.iterator();

  25:         

  26:         while(it.hasNext()) {

  27:             Item item = (Item)it.next();

  28:             buffer.append(item.makeHTML());

  29:         }

  30:         

  31:         buffer.append("</ul>\n");

  32:         buffer.append("<hr><address>" + author + "</address>");

  33:         buffer.append("</body></html>\n");

  34:         

  35:         return buffer.toString();

  36:     }

  37:  

  38: }

抽象的な工場: Factoryクラス

   1: package factory;

   2:  

   3: public abstract class Factory {

   4:     public static Factory getFactory(String classname) {

   5:         Factory factory = null;

   6:         

   7:         try {

   8:             factory = (Factory)Class.forName(classname).newInstance();

   9:         } catch (ClassNotFoundException e) {

  10:             System.err.println("クラス " + classname + " が見つかりません。");

  11:         } catch (Exception e) {

  12:             e.printStackTrace();

  13:         }

  14:         

  15:         return factory;

  16:     }

  17:     

  18:     public abstract Link createLink(String caption, String url);

  19:     public abstract Tray createTray(String caption);

  20:     public abstract Page createPage(String title, String author);

  21: }

具体的な工場: ListFactoryクラス

   1: package listfactory;

   2:  

   3: import factory.Factory;

   4: import factory.Link;

   5: import factory.Page;

   6: import factory.Tray;

   7:  

   8: public class ListFactory extends Factory {

   9:     public Link createLink(String caption, String url) {

  10:         return new ListLink(caption, url);

  11:     }

  12:  

  13:     @Override

  14:     public Tray createTray(String caption) {

  15:         return new ListTray(caption);

  16:     }

  17:  

  18:     @Override

  19:     public Page createPage(String title, String author) {

  20:         return new ListPage(title, author);

  21:     }

  22: }

Mainクラス

   1: import factory.*;

   2:  

   3: public class Main {

   4:  

   5:     /**

   6:      * @param args

   7:      */

   8:     public static void main(String[] args) {

   9:         if (args.length != 1) {

  10:             System.out.println("Usage: java Main class.name.of.ConcreteFactory");

  11:             System.out.println("Example 1: java Main listfactory.ListFactory");

  12:             System.out.println("Example 2: java Main tablefactory.TableFactory");

  13:             System.exit(0);

  14:         }

  15:         

  16:         Factory factory = Factory.getFactory(args[0]);

  17:         

  18:         Link asahi = factory.createLink("朝日新聞", "http://www.asahi.com/");

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

  20:         

  21:         Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");

  22:         Link jp_yahoo = factory.createLink("Yahoo!Japan", "http://www.yahoo.co.jp/");

  23:         Link excite = factory.createLink("Excite", "http://www.excite.com/");

  24:         Link google = factory.createLink("Google", "http://www.google.com");

  25:         

  26:         Tray traynews = factory.createTray("新聞");

  27:         traynews.add(asahi);

  28:         traynews.add(yomiuri);

  29:         

  30:         Tray trayyahoo = factory.createTray("Yahoo!");

  31:         trayyahoo.add(us_yahoo);

  32:         trayyahoo.add(jp_yahoo);

  33:         

  34:         Tray traysearch = factory.createTray("サーチエンジン");

  35:         traysearch.add(trayyahoo);

  36:         traysearch.add(excite);

  37:         traysearch.add(google);

  38:         

  39:         Page page = factory.createPage("LinkPage", "ヤン炳");

  40:         page.add(traynews);

  41:         page.add(traysearch);

  42:         page.output();

  43:     }

  44:  

  45: }

出力されたHTMLファイルは以下のようになっております。

   1: <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

   2: <title>LinkPage</title></head>

   3: <body>

   4: <h1>LinkPage</h1>

   5: <ul>

   6: <li>

   7: 新聞

   8: <ul>

   9:  <li><a href="http://www.asahi.com/">朝日新聞</a></li>

  10:  <li><a href="http://www.yomiuri.co.jp/">読売新聞</a></li>

  11: </ul>

  12: </li>

  13: <li>

  14: サーチエンジン

  15: <ul>

  16: <li>

  17: Yahoo!

  18: <ul>

  19:  <li><a href="http://www.yahoo.com/">Yahoo!</a></li>

  20:  <li><a href="http://www.yahoo.co.jp/">Yahoo!Japan</a></li>

  21: </ul>

  22: </li>

  23:  <li><a href="http://www.excite.com/">Excite</a></li>

  24:  <li><a href="http://www.google.com">Google</a></li>

  25: </ul>

  26: </li>

  27: </ul>

  28: <hr><address>ヤン炳</address></body></html>

次は、TableFactoryを作りましょう。仕組みはListFactory系のと同じです。

広告

Singletonパターン

Singletonの役

  Singletonパターンには、Singletonの役しか登場しません。Singletonの役は、唯一のインスタンスを得るためのstaticメソッドを持っています。このメソッドはいつも同じインスタンスを返します。

   1: public class Singlrton {

   2:    private static Singleton singleton = new Singleton();

   3:    private Singleton() {

   4:       System.out.println("インスタンスを生成しました。");

   5:    }

   6:    public static Singleton getInstance() {

   7:       return singleton;

   8:    }

   9: }

コメント:

以下の書き方は厳密にはSingletonパターンになりません。

private static Singleton singleton = null;

getInstance()メソッドにsingleton = new Singleton()にします。マルチスレッドの原因で、インスタンスが数個作れることになります。