Builder と Abstract Factory S. Yukita [email protected] 1. Builder パターン 使われ所 • 大きなインスタンスを組み上げる場合。 • インスタンスの組み上げにパターンがある とき,パターンをディレクタに固定する。 • 組み上げパターンに従って実際の仕事を するのはBuilderインタフェース(抽象クラ ス)を実装(具象化)するクラス。 デザインパターン 第4回 2 uses Main Director builder construct 例 題 の ク ラ ス 図 TextBuilder makeTitle makeString makeItems getResult デザインパターン 第4回 Builder makeTitle makeString makeItems getResult HTMLBuilder makeTitle makeString makeItems getResult 3 Builder.java public abstract class Builder { public abstract void makeTitle(String title); public abstract void makeString(String str); public abstract void makeItems(String[] items); public abstract Object getResult(); } デザインパターン 第4回 4 TextBuilder.java (1) public class TextBuilder extends Builder { private StringBuffer buffer = new StringBuffer(); public void makeTitle(String title) { buffer.append("==============================\n"); buffer.append("『" + title + "』\n"); buffer.append("\n"); } デザインパターン 第4回 5 TextBuilder.java (2) public void makeString(String str) { buffer.append('■' + str + "\n"); buffer.append("\n"); } デザインパターン 第4回 6 TextBuilder.java (3) public void makeItems(String[] items) { for (int i = 0; i < items.length; i++) { buffer.append(" ・" + items[i] + "\n"); } buffer.append("\n"); } デザインパターン 第4回 7 TextBuilder.java (4) public Object getResult() { buffer.append("==============================\n"); return buffer.toString(); } } デザインパターン 第4回 8 HTMLBuilder.java (1) import java.io.*; public class HTMLBuilder extends Builder { private String filename; private PrintWriter writer; デザインパターン 第4回 9 HTMLBuilder.java (2) public void makeTitle(String title) { filename = title + ".html"; try { writer = new PrintWriter(new FileWriter(filename)); } catch (IOException e) { e.printStackTrace(); } writer.println( "<html><head><title>" + title + "</title></head><body>"); writer.println("<h1>" + title + "</h1>"); } デザインパターン 第4回 10 HTMLBuilder.java (3) public void makeString(String str) { writer.println("<p>" + str + "</p>"); } public void makeItems(String[] items) { writer.println("<ul>"); for (int i = 0; i < items.length; i++) { writer.println("<li>" + items[i] + "</li>"); } writer.println("</ul>"); } デザインパターン 第4回 11 HTMLBuilder.java (4) public Object getResult() { writer.println("</body></html>"); writer.close(); return filename; } } デザインパターン 第4回 12 Director.java (1) public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } デザインパターン 第4回 13 public Object construct() { Director.java (2) builder.makeTitle("Greeting"); builder.makeString("朝から昼にかけて"); builder.makeItems(new String[]{ "おはようございます。", "こんにちは。" }); builder.makeString("夜に"); builder.makeItems(new String[]{ "こんばんは。", "おやすみなさい。", "さようなら。" }); return builder.getResult(); } } デザインパターン 第4回 14 Main.java (1) public class Main { public static void main(String[] args) { if (args.length != 1) { usage(); System.exit(0); } デザインパターン 第4回 15 if (args[0].equals("plain")) { Main.java (2) Director director = new Director( new TextBuilder()); String result = (String)director.construct(); System.out.println(result); } else if (args[0].equals("html")) { Director director = new Director( new HTMLBuilder()); String filename = (String)director.construct(); System.out.println(filename + "が作成されました。"); } else { usage(); System.exit(0); } } デザインパターン 第4回 16 Main.java (3) public static void usage() { System.out.println( "Usage: java Main plain プレーンテキストで文書作成"); System.out.println( "Usage: java Main html HTMLファイルで文書作成"); } } デザインパターン 第4回 17 実行結果(plain) java Main plain ================================= [Greeting] ■朝から昼にかけて ・おはようございます。 ・こんにちは。 ■夜に ・こんばんは。 ・おやすみなさい。 ・さようなら。 ================================= デザインパターン 第4回 18 実行結果(HTML) java Main html Greeting.htmlが作成されました。 <html><head><title>Greeting</title></head><body> <h1>Greeting</h1> <p>朝から昼にかけて</p> <ul> <li>おはようございます。</li> <li>こんにちは。</li> </ul> <p>夜にかけて</p> <ul> <li>こんばんは。</li> <li>おやすみなさい。</li> <li>さようなら。</li> </ul> </body></html> デザインパターン 第4回 19 パターン uses Client Director builder construct Builder buildPart1 buildPart2 buildPart3 getResult ConcreteBuilder buildPart1 buildPart2 buildPart3 getResult デザインパターン 第4回 20 Sequence 図 :Client :Director construct :ConcreteBuilder buildPart1 デザインパターン 第4回 21 2. Abstract Factory パターン 類似のパターンとの比較 • Builder パターンでは Builder の抽象メソッドを Director が次々呼び出すことによって大きなイン スタンスを部分を徐々に構築する。 • Abstract Factory パターンは,インスタンス群の生 成とそれらのネットワーク配線に力点をおく。イン スタンス生成方法および配線方法を抽象化する。 • Factory Method パターンはインスタンス生成を環 境との配線とともに行う定石を抽象化している。 デザインパターン 第4回 22 例 題 の ク ラ ス 図 ( 抽 象 ク ラ ス ) Item caption makeHTML Link url tray makeHTML add makeHTML creates Page Tray creates Factory getFactory createLink createTray createPage デザインパターン 第4回 title author content add output makeHTML creates 23 例 題 の ク ラ ス 図 ( 具 象 ク ラ ス ) ListLink ListTray ListPage makeHTML makeHTML makeHTML creates creates ListFactory createLink createTray createPage デザインパターン 第4回 creates 24 Item.java package factory; public abstract class Item { protected String caption; public Item(String caption) { this.caption = caption; } public abstract String makeHTML(); } デザインパターン 第4回 25 Link.java package factory; public abstract class Link extends Item { protected String url; public Link(String caption, String url) { super(caption); this.url = url; } } デザインパターン 第4回 26 Tray.java package factory; import java.util.Vector; public abstract class Tray extends Item { protected Vector tray = new Vector(); public Tray(String caption) { super(caption); } public void add(Item item) { tray.add(item); } } デザインパターン 第4回 27 Page.java(1) package factory; import java.io.*; import java.util.Vector; public abstract class Page { protected String title; protected String author; protected Vector content = new Vector(); デザインパターン 第4回 28 Page.java(2) public Page(String title, String author) { this.title = title; this.author = author; } public void add(Item item) { content.add(item); } デザインパターン 第4回 29 public void output() { Page.java(3) try { String filename = title + ".html"; Writer writer = new FileWriter(filename); writer.write(this.makeHTML()); writer.close(); System.out.println(filename + " を作成し ました。"); } catch (IOException e) {e.printStackTrace();} } デザインパターン 第4回 30 Page.java(4) public abstract String makeHTML(); } デザインパターン 第4回 31 Factory.java(1) package factory; public abstract class Factory { public static Factory getFactory(String classname) { Factory factory = null; try { factory = (Factory)Class.forName(classname).newInstance(); } catch (ClassNotFoundException e) { System.err.println("クラス " + classname + " が見つかりま せん。"); } catch (Exception e) {e.printStackTrace();} return factory; } デザインパターン 第4回 32 Factory.java(2) public abstract Link createLink(String caption, String url); public abstract Tray createTray(String caption); public abstract Page createPage(String title, String author); } デザインパターン 第4回 33 package listfactory; ListLink.java import factory.*; public class ListLink extends Link { public ListLink(String caption, String url) { super(caption, url); } public String makeHTML() { return " <li><a href=\"" + url + "\">" + caption + "</a></li>\n"; } } デザインパターン 第4回 34 ListTray.java(1) package listfactory; import factory.*; import java.util.Iterator; public class ListTray extends Tray { public ListTray(String caption) { super(caption); } デザインパターン 第4回 35 public String makeHTML() { ListTray.java(2) StringBuffer buffer = new StringBuffer(); buffer.append("<li>\n"); buffer.append(caption + "\n"); buffer.append("<ul>\n"); Iterator it = tray.iterator(); while (it.hasNext()) { Item item = (Item)it.next(); buffer.append(item.makeHTML()); } buffer.append("</ul>\n"); buffer.append("</li>\n"); return buffer.toString(); } } デザインパターン 第4回 36 ListPage.java(1) package listfactory; import factory.*; import java.util.Iterator; public class ListPage extends Page { public ListPage(String title, String author) { super(title, author); } デザインパターン 第4回 37 ListPage.java(2) public String makeHTML() { StringBuffer buffer = new StringBuffer(); buffer.append("<html><head><title>" + title + "</title></head>\n"); buffer.append("<body>\n"); buffer.append("<h1>" + title + "</h1>\n"); buffer.append("<ul>\n"); デザインパターン 第4回 38 ListPage.java(3) Iterator it = content.iterator(); while (it.hasNext()) { Item item = (Item)it.next(); buffer.append(item.makeHTML()); } デザインパターン 第4回 39 ListPage.java(4) buffer.append("</ul>\n"); buffer.append("<hr><address>" + author + "</address>"); buffer.append("</body></html>\n"); return buffer.toString(); } } デザインパターン 第4回 40 ListFactory.java(1) package listfactory; import factory.*; public class ListFactory extends Factory { public Link createLink(String caption, String url){ return new ListLink(caption, url); } デザインパターン 第4回 41 ListFactory.java(2) public Tray createTray(String caption) { return new ListTray(caption); } public Page createPage(String title, String author) { return new ListPage(title, author); } } デザインパターン 第4回 42 import factory.*; Main.java(1) public class Main { public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: java Main class.name.of.ConcreteFactory"); System.out.println("Example 1: java Main listfactory.ListFactory"); System.out.println("Example 2: java Main tablefactory.TableFactory"); System.exit(0); } デザインパターン 第4回 43 Main.java(2) Factory factory =Factory.getFactory(args[0]); Link asahi = factory.createLink(“朝日新聞”, "http://www.asahi.com/"); Link yomiuri = factory.createLink(“読売新聞”, "http://www.yomiuri.co.jp/"); デザインパターン 第4回 44 Main.java(3) Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/"); Link jp_yahoo =factory.createLink("Yahoo!Japan", "http://www.yahoo.co.jp/"); Link excite = factory.createLink("Excite", "http://www.excite.com/"); Link google = factory.createLink("Google", "http://www.google.com/"); デザインパターン 第4回 45 Main.java(4) Tray traynews = factory.createTray("新聞"); traynews.add(asahi); traynews.add(yomiuri); Tray trayyahoo= factory.createTray("Yahoo!"); trayyahoo.add(us_yahoo); trayyahoo.add(jp_yahoo); デザインパターン 第4回 46 Main.java(5) Tray traysearch = factory.createTray("サーチエンジン"); traysearch.add(trayyahoo); traysearch.add(excite); traysearch.add(google); デザインパターン 第4回 47 Main.java(6) Page page = factory.createPage("LinkPage", "結城 浩"); page.add(traynews); page.add(traysearch); page.output(); } } デザインパターン 第4回 48 実行方法 java Main listFactory.ListFactory デザインパターン 第4回 49 生成されたHTMLをブラウザでみると LinkPage •新聞 •朝日新聞 •読売新聞 •サーチエンジン •Yahoo! •Yahoo! •Yahoo!Japan •Excite •Google デザインパターン 第4回 50 パターン AbstractProduct1 excecuteA excecuteB AbstractFactory creates createProduct1 createProduct2 ...... ConcreteProduct1 excecuteA excecuteB AbstractFactory creates createProduct1 createProduct2 ...... デザインパターン 第4回 51 AbstractProduct1 Main excecuteA excecuteB 演出家 AbstractFactory creates createProduct1 createProduct2 ...... 役 ConcreteProduct1 excecuteA excecuteB ConcreteFactory creates たとえ話 役者 createProduct1 createProduct2 ...... デザインパターン 第4回 52
© Copyright 2024 ExpyDoc