2018-1-21 by Atlas
- 設計思想
客戶類和工廠類分開。消費者任何時候需要某套產品集合時,只需向抽象工廠請求即可。抽象工廠會再向具體的工廠生產出符合產品集規格的產品。
- 應用場景
抽象替代具體,降低客戶方對具體工廠的耦合,只給客戶方提供接口和抽象類。
優點:降低依賴具體,降低耦合。
缺點:完工的工廠越多,新增其他零件需要的修改就越多。
- UML 類圖
- AbstractProduct(抽象產品)參與者
AbstractProduct參與者規定由AbstractFactory參與者所產生的抽象零件和產品的接口。- AbstractFactory(抽象工廠)參與者
AbstractFactory參與者規定用來產生AbstractProduct參與者的對象實例的接口。- Client(客戶)參與者
Client參與者是一個只使用AbstractFactory參與者和AbstractProduct參與者的接口來完成工作的參與者。Client參與者並不知道具體零件、產品和工廠。- ConcreteProduct(具體產品)參與者
ConcreteProduct參與者是AbstractProduct參與者的具體實現。- ConcreteFactory(具體工廠)參與者
ConcreteFactory參與者是AbstractFactory參與者的具體實現。
- 標準示例
public abstract class Item {
protected String caption;
public Item(String caption){
this.caption = caption;
}
public abstract String makeHTML();
}
public abstract class Link extends Item {
protected String url;
public Link(String caption, String url){
super(caption);
this.url = url;
}
}
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);
}
}
public abstract class Page {
protected String title;
protected String autor;
protected Vector content = new Vector();
public Page(String title, String autor){
this.title = title;
this.autor = autor;
}
public void add(Item item){
content.add(item);
}
public abstract String makeHTML();
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();
}
}
}
public abstract class Factory {
public static Factory getFactory(String className){
Factory factory = null;
try {
factory = (Factory) Class.forName(className).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception ex){
ex.printStackTrace();
}
return factory;
}
public abstract Link createLink(String caption, String url);
public abstract Tray createTray(String caption);
public abstract Page createPage(String title, String autor);
}
public class ListLink extends Link {
public ListLink(String caption, String url){
super(caption, url);
}
@Override
public String makeHTML() {
return "<li><a href=\"" + url + "\">" + caption + "</a></li>\n";
}
}
public class ListTray extends Tray {
public ListTray(String caption){
super(caption);
}
@Override
public String makeHTML() {
StringBuffer buffer = new StringBuffer();
buffer.append("<li>\n");
buffer.append(caption).append("\n");
buffer.append("<ul>\n");
Iterator iterator = tray.iterator();
while(iterator.hasNext()){
Item item = (Item) iterator.next();
buffer.append(item.makeHTML());
}
buffer.append("</ul>\n");
buffer.append("</li>\n");
return buffer.toString();
}
}
public class ListPage extends Page {
public ListPage(String title, String autor){
super(title, autor);
}
@Override
public String makeHTML() {
StringBuffer buffer = new StringBuffer();
buffer.append("<html><head><title>").append(title).append("</title></head>\n");
buffer.append("<body>\n");
buffer.append("<h1>").append(title).append("</h1>\n");
buffer.append("<ul>\n");
Iterator iterator = content.iterator();
while(iterator.hasNext()){
Item item = (Item) iterator.next();
buffer.append(item.makeHTML());
}
buffer.append("</ul>\n");
buffer.append("<hr><address>").append(autor).append("</address>");
buffer.append("</body><html>\n");
return buffer.toString();
}
}
public class ListFactory extends Factory {
@Override
public Link createLink(String caption, String url) {
return new ListLink(caption, url);
}
@Override
public Tray createTray(String caption) {
return new ListTray(caption);
}
@Override
public Page createPage(String title, String autor) {
return new ListPage(title, autor);
}
}
public class Main {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String className = scanner.next();
Factory factory = Factory.getFactory(className);
Link asahi = factory.createLink("朝日新聞", "http://www.asahi.com/");
Link yomiuri = factory.createLink("讀賣新聞", "http://www.yomiuri.co.jp/");
Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");
Link google = factory.createLink("Google", "http://www.google.com/");
Tray trayews = factory.createTray("新聞");
trayews.add(asahi);
trayews.add(yomiuri);
Tray trayyahoo = factory.createTray("Yahoo!");
trayyahoo.add(us_yahoo);
Tray traysearch = factory.createTray("搜索引擎");
traysearch.add(google);
Page page = factory.createPage("LinkPage", "Atlas");
page.add(trayews);
page.add(trayyahoo);
page.add(traysearch);
page.output();
}
}
抽象產品參與者是Link類、Tray類和Page類。
抽象工廠參與者是Factory類。
具體產品參與者是ListLink類、ListTray類和ListPage類。
具體工廠參與者是ListFactory類。
- 案例鑑賞
搜尋中...