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类。
- 案例鉴赏
搜寻中...