读书笔记 仅供参考
Abstract Factory
抽象工厂的工作室将抽象零件组装为抽象产品。
我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装成为产品。
UML 和角色
AbstractProduct
负责定义 AbstractFactory 角色所生成的抽象零件和产品的接口(API)
AbstractFactory
负责定义用于生成抽象产品的接口(API)
ConcreteProduct
负责实现 AbstractProduct 角色的接口(API)
ConcreateFactory
负责实现 AbstractFactory 角色的接口(API)
UML
例子
例子大体是使用抽象工厂模式来组装一个 html 文件,零件就要 Link 和 Tray,最后组装成一个 Page,写入文件。
UML
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();
}
}
优缺点
优点是易于添加新的具体的工厂,方法都已经定义好了。
缺点是难以添加新的零件,需要修改所有的工厂。