builder と abstract factory s. yukita [email protected]

52
Builder と Abstract Fa ctory S. Yukita [email protected]

Upload: rosamond-dennis

Post on 17-Dec-2015

215 views

Category:

Documents


1 download

TRANSCRIPT

Builder と Abstract Factory

S. Yukita

[email protected]

デザインパターン 第4回 2

1. Builder パターン使われ所

• 大きなインスタンスを組み上げる場合。• インスタンスの組み上げにパターンが

あるとき,パターンをディレクタに固定する。

• 組み上げパターンに従って実際の仕事をするのは Builder インタフェース(抽象クラス)を実装(具象化)するクラス。

デザインパターン 第4回 3

例題のクラス図

Main Director

builder

construct

Builder

makeTitle

makeString

makeItems

getResult

TextBuilder

makeTitle

makeString

makeItems

getResult

HTMLBuilder

makeTitle

makeString

makeItems

getResult

uses

デザインパターン 第4回 4

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回 5

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回 6

TextBuilder.java (2)

public void makeString(String str) {

buffer.append('■' + str + "\n");

buffer.append("\n");

}

デザインパターン 第4回 7

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回 8

TextBuilder.java (4)

public Object getResult() {

buffer.append("==============================\n");

return buffer.toString();

}

}

デザインパターン 第4回 9

HTMLBuilder.java (1)

import java.io.*;

public class HTMLBuilder extends Builder {

private String filename;

private PrintWriter writer;

デザインパターン 第4回 10

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回 11

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回 12

HTMLBuilder.java (4)

public Object getResult() {

writer.println("</body></html>");

writer.close();

return filename;

}

}

デザインパターン 第4回 13

Director.java (1)

public class Director {

private Builder builder;

public Director(Builder builder) {

this.builder = builder;

}

デザインパターン 第4回 14

Director.java (2) public Object construct() {

builder.makeTitle("Greeting");

builder.makeString(" 朝から昼にかけて ");

builder.makeItems(new String[]{

" おはようございます。 ", " こんにちは。 " });

builder.makeString(" 夜に ");

builder.makeItems(new String[]{

" こんばんは。 ", " おやすみなさい。 ", " さようなら。" });

return builder.getResult();

}

}

デザインパターン 第4回 15

Main.java (1)

public class Main {

public static void main(String[] args) {

if (args.length != 1) {

usage();

System.exit(0);

}

デザインパターン 第4回 16

Main.java (2) if (args[0].equals("plain")) {

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回 17

Main.java (3) public static void usage() {

System.out.println(

"Usage: java Main plain プレーンテキストで文書作成");

System.out.println(

"Usage: java Main html HTML ファイルで文書作成");

}

}

デザインパターン 第4回 18

実行結果 (plain)

java Main plain=================================[Greeting]■朝から昼にかけて ・おはようございます。 ・こんにちは。■夜に ・こんばんは。 ・おやすみなさい。 ・さようなら。=================================

デザインパターン 第4回 19

実行結果 (HTML)java Main htmlGreeting.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回 20

パターンClient Director

builder

construct

Builder

buildPart1

buildPart2

buildPart3

getResult

ConcreteBuilder

buildPart1

buildPart2

buildPart3

getResult

uses

デザインパターン 第4回 21

Sequence 図:Client :Director :ConcreteBuilder

constructbuildPart1

デザインパターン 第4回 22

2. Abstract Factory パターン類似のパターンとの比較

• Builder パターンでは Builder の抽象メソッドを Director が次々呼び出すことによって大きなインスタンスを部分を徐々に構築する。

• Abstract Factory パターンは,インスタンス群の生成とそれらのネットワーク配線に力点をおく。インスタンス生成方法および配線方法を抽象化する。

• Factory Method パターンはインスタンス生成を環境との配線とともに行う定石を抽象化している。

デザインパターン 第4回 23

例題のクラス図

抽象クラス)

Item

caption

makeHTML

Link

url

makeHTML

Tray

tray

add

makeHTML

Page

title

author

content

add

output

makeHTMLFactory

getFactory

createLink

createTray

createPage

creates creates

creates

デザインパターン 第4回 24

例題のクラス図

具象クラス)

ListLink

makeHTML

ListTray

makeHTML

ListPage

makeHTML

ListFactory

createLink

createTray

createPage

creates creates

creates

デザインパターン 第4回 25

Item.javapackage factory;

public abstract class Item {

protected String caption;

public Item(String caption) {

this.caption = caption;

}

public abstract String makeHTML();

}

デザインパターン 第4回 26

Link.javapackage factory;

public abstract class Link extends Item {

protected String url;

public Link(String caption, String url) {

super(caption);

this.url = url;

}

}

デザインパターン 第4回 27

Tray.javapackage 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回 28

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回 29

Page.java(2)

public Page(String title, String author) {

this.title = title;

this.author = author;

}

public void add(Item item) {

content.add(item);

}

デザインパターン 第4回 30

Page.java(3) public void output() {

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回 31

Page.java(4)

public abstract String makeHTML();

}

デザインパターン 第4回 32

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回 33

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回 34

ListLink.javapackage listfactory;

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回 35

ListTray.java(1)

package listfactory;

import factory.*;

import java.util.Iterator;

public class ListTray extends Tray {

public ListTray(String caption) {

super(caption);

}

デザインパターン 第4回 36

ListTray.java(2) public String makeHTML() {

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回 37

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回 38

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回 39

ListPage.java(3) Iterator it = content.iterator();

while (it.hasNext()) {

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

buffer.append(item.makeHTML());

}

デザインパターン 第4回 40

ListPage.java(4)

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

buffer.append("<hr><address>"

+ author + "</address>");

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

return buffer.toString();

}

}

デザインパターン 第4回 41

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回 42

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回 43

Main.java(1)import factory.*;

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回 44

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回 45

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回 46

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回 47

Main.java(5) Tray traysearch =

factory.createTray(" サーチエンジン ");

traysearch.add(trayyahoo);

traysearch.add(excite);

traysearch.add(google);

デザインパターン 第4回 48

Main.java(6)

Page page = factory.createPage("LinkPage",

" 結城 浩 ");

page.add(traynews);

page.add(traysearch);

page.output();

}

}

デザインパターン 第4回 49

実行方法

java Main listFactory.ListFactory

デザインパターン 第4回 50

生成された HTML をブラウザでみると

LinkPage•新聞

•朝日新聞 •読売新聞

•サーチエンジン •Yahoo!

•Yahoo! •Yahoo!Japan

•Excite •Google

デザインパターン 第4回 51

パターンAbstractProduct1

excecuteA

excecuteBAbstractFactory

createProduct1

createProduct2

......

ConcreteProduct1

excecuteA

excecuteB AbstractFactory

createProduct1

createProduct2

......

creates

creates

デザインパターン 第4回 52たとえ話

AbstractProduct1

excecuteA

excecuteBAbstractFactory

createProduct1

createProduct2

......

ConcreteProduct1

excecuteA

excecuteB ConcreteFactory

createProduct1

createProduct2

......

creates

creates

役者

Main

演出家