1. AbstractFactory模式
抽象工厂将“抽象零件”组装为“抽象产品”
1.1 AbstractFactory模式的类图
登场角色:
-
AbstractProduct(抽象产品)
定义了抽象工厂所生成的抽象零件和产品的接口(API) -
AbstractFactory(抽象工厂)
定义抽象产品的接口(API) -
Client(使用者)
调用AbstractFactory角色和AbstractProduct角色的接口进行工作 -
ConcreteProduct(具体产品)
实现了AbstractProduct的接口 -
ConcreteFactory(具体通常)
实现了AbstractFactory的接口
1.2 示例程序
类一览表
名字 | 说明 |
---|---|
Factory | 抽象工厂类 |
Item | 抽象零件Link和Tray的接口 |
Link | 一个抽象零件:链接类 |
Tray | 一个抽象零件:可含有Link和Tray的类 |
Page | 一个抽象零件:表示HTML页面 |
ListFactory | 具体的工厂类 |
ListLink | 具体零件 |
ListTray | 具体零件 |
ListPage | 具体零件 |
Main | 测试类 |
uml类图(只含继承关系)
uml类图
Factory类
package xin.ajay.abstractfactory.framework;
public abstract class Factory {
public static Factory getFactory(String classname){
Factory factory = null;
try {
factory = (Factory) Class.forName(classname).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return factory;
}
public abstract Link createLink(String caption,String url);
public abstract Tray createTray(String caption);
public abstract Page createPage(String title,String author);
}
Item类
package xin.ajay.abstractfactory.framework;
public abstract class Item{
protected String caption;
public Item(String caption){
this.caption = caption;
}
public abstract String makeHTML();
}
Link类
package xin.ajay.abstractfactory.framework;
public abstract class Link extends Item {
protected String url;
public Link(String caption,String url){
super(caption);
this.url = url;
}
}
Page类
package xin.ajay.abstractfactory.framework;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
public abstract class Page {
protected String title;
protected String author;
protected List<Item> content = new ArrayList<>();
public Page(String title,String author){
this.title = title;
this.author = author;
}
public void add(Item item){
content.add(item);
}
public void output(){
String filename = title +".html";
try {
Writer writer = new FileWriter(filename);
writer.write(makeHTML());
writer.close();
System.out.println(filename + "编写完成");
} catch (IOException e) {
e.printStackTrace();
}
}
public abstract String makeHTML();
}
Tray类
package xin.ajay.abstractfactory.framework;
import java.util.ArrayList;
import java.util.List;
public abstract class Tray extends Item {
protected List<Item> tray = new ArrayList<>();
public Tray(String caption) {
super(caption);
}
public void add(Item item){
tray.add(item);
}
}
ListFactory类
package xin.ajay.abstractfactory.impl;
import xin.ajay.abstractfactory.framework.Factory;
import xin.ajay.abstractfactory.framework.Link;
import xin.ajay.abstractfactory.framework.Page;
import xin.ajay.abstractfactory.framework.Tray;
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 author) {
return new ListPage(title,author);
}
}
ListLink类
package xin.ajay.abstractfactory.impl;
import xin.ajay.abstractfactory.framework.Link;
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";
}
}
ListPage类
package xin.ajay.abstractfactory.impl;
import xin.ajay.abstractfactory.framework.Item;
import xin.ajay.abstractfactory.framework.Page;
import java.util.Iterator;
public class ListPage extends Page {
public ListPage(String title, String author) {
super(title, author);
}
@Override
public String makeHTML() {
StringBuilder builder = new StringBuilder();
builder.append("<html><head><title>"+title+"</title></head>\n");
builder.append("<body>\n");
builder.append("<h1>" + title + "</h1>\n");
builder.append("<ul>\n");
Iterator<Item> iterator = content.iterator();
while (iterator.hasNext()){
Item item = iterator.next();
builder.append(item.makeHTML());
}
builder.append("</ul>\n");
builder.append("<hr><address>" + author + "</address>");
builder.append("</body></html>\n");
return builder.toString();
}
}
ListTray类
package xin.ajay.abstractfactory.impl;
import xin.ajay.abstractfactory.framework.Item;
import xin.ajay.abstractfactory.framework.Tray;
import java.util.Iterator;
public class ListTray extends Tray {
public ListTray(String caption) {
super(caption);
}
@Override
public String makeHTML() {
StringBuilder builder = new StringBuilder();
builder.append("<li>\n");
builder.append(caption + "\n");
builder.append("<ul>\n");
for (Item item : tray) {
builder.append(item.makeHTML());
}
builder.append("</ul>\n");
builder.append("</li>\n");
return builder.toString();
}
}
Main类
package xin.ajay.abstractfactory.impl;
import xin.ajay.abstractfactory.framework.Factory;
import xin.ajay.abstractfactory.framework.Link;
import xin.ajay.abstractfactory.framework.Page;
import xin.ajay.abstractfactory.framework.Tray;
public class Main {
public static void main(String[] args) {
Factory factory = Factory.getFactory("xin.ajay.abstractfactory.impl.ListFactory");
Link people = factory.createLink("人民日报", "http://www.people.com.cn/");
Link gmw = factory.createLink("光明日报", "http://www.gme.cn/");
Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");
Link cn_yahoo = factory.createLink("Baidu","https://sg.yahoo.com/");
Link excite = factory.createLink("Excite", "http://www.excite.com/");
Link google = factory.createLink("Google", "http://www.google.com/");
Tray traynews = factory.createTray("日报");
traynews.add(people);
traynews.add(gmw);
Tray trayyahoo = factory.createTray("Yahoo!");
trayyahoo.add(us_yahoo);
trayyahoo.add(cn_yahoo);
Tray traysearch = factory.createTray("检索引擎");
traysearch.add(trayyahoo);
traysearch.add(excite);
traysearch.add(google);
Page page = factory.createPage("LinkPage", "cn");
page.add(traynews);
page.add(traysearch);
page.output();
}
}
结果
生成的Page页面
<html><head><title>LinkPage</title></head>
<body>
<h1>LinkPage</h1>
<ul>
<li>
日报
<ul>
<li><a href="http://www.people.com.cn/">人民日报</a></li>
<li><a href="http://www.gme.cn/">光明日报</a></li>
</ul>
</li>
<li>
检索引擎
<ul>
<li>
Yahoo!
<ul>
<li><a href="http://www.yahoo.com/">Yahoo!</a></li>
<li><a href="https://sg.yahoo.com/">Baidu</a></li>
</ul>
</li>
<li><a href="http://www.excite.com/">Excite</a></li>
<li><a href="http://www.google.com/">Google</a></li>
</ul>
</li>
</ul>
<hr><address>cn</address></body></html>
鸣谢
GoF《设计模式》和结城浩的《图解设计模式》