读书笔记 仅供参考
Abstract Factory
抽象工厂的工作室将抽象零件组装为抽象产品。
我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装成为产品。
UML 和角色
AbstractProduct
负责定义 AbstractFactory 角色所生成的抽象零件和产品的接口(API)
AbstractFactory
负责定义用于生成抽象产品的接口(API)
ConcreteProduct
负责实现 AbstractProduct 角色的接口(API)
#### ConcreateFactory
负责实现 AbstractFactory 角色的接口(API)
#### UML
例子
例子大体是使用抽象工厂模式来组装一个 html 文件,零件就要 Link 和 Tray,最后组装成一个 Page,写入文件。
包 | 类名 | 说明 |
---|---|---|
factory | Factory | 抽象类,代表工厂, 根据不同情况返回不同工厂 |
factory | Item | 抽象类,所有零件的父类(不包括 Page) |
factory | Link | 抽象类,代表链接 |
factory | Tray | 抽象类,代表容器 |
factory | Page | 抽象类,代表网页 |
无 | Main | 测试 |
listFactory | ListFactory | 工厂,可以生产下面三种零件 |
listFactory | ListLink | 链接,输出 HTML 字符串 |
listFactory | ListTray | 容器,输出 HTML 字符串 |
listFactory | ListPage | 页面,输出 HTML 字符串 |
tableFactory | TableFactory | 工厂,可以生产下面三种零件 |
tableFactory | TableLink | 链接,输出 HTML 字符串 |
tableFactory | TableTray | 容器,输出 HTML 字符串 |
tableFactory | TablePage | 页面,输出 HTML 字符串 |
public abstract class Factory {
//根据不同参数得到不同工厂的实例
public static Factory getFactory(String className) {
Factory factory = null;
try {
factory = (Factory) Class.forName(className).newInstance();
} catch (ClassNotFoundException e) {
System.out.println("not found " + className + " class");
} catch (Exception 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);
}
//代表项目,是 Link 和 Tray 的父类
public abstract class Item {
//项目的标题
protected String caption;
public Item(String caption) {
this.caption = caption;
}
public abstract String makeHtml();
}
//表示 HYML 超链接的类
public abstract class Link extends Item{
protected String url;
public Link(String caption, String url) {
super(caption);
this.url = url;
}
}
//抽象地表示 HTML 页面的类,可以看作是零件组成的产品
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() {
try {
String fileNmae = "file/abstractFactory/" + title + ",html";
Writer writer = new FileWriter(fileNmae);
writer.write(this.makeHtml());
writer.close();
System.out.println(fileNmae + "编写完成");
} catch (IOException e) {
e.printStackTrace();
}
}
public abstract String makeHtml();
}
//Tray 类表示一个含有多个 Link 类和 Tray 类的容器。
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);
}
}
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);
}
}
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 ListPage extends Page {
public ListPage(String title, String author) {
super(title, author);
}
@Override
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");
Iterator<Item> it = content.iterator();
while (it.hasNext()) {
Item item = it.next();
buffer.append(item.makeHtml());
}
buffer.append("</ul>\n");
buffer.append("<hr><address>" + author + "</address>");
buffer.append("</body></html>\n");
return buffer.toString();
}
}
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 + "\n");
buffer.append("<ul>\n");
Iterator<Item> it = tray.iterator();
while (it.hasNext()) {
Item item = it.next();
buffer.append(item.makeHtml());
}
buffer.append("</ul>\n");
buffer.append("</li>\n");
return buffer.toString();
}
}
UML
优缺点
优点是易于添加新的具体的工厂,方法都已经定义好了。
缺点是难以添加新的零件,需要修改所有的工厂。