文章目录
AbstractFactory模式
Abstract的意思是“抽象的”,Factory的意思是“工厂”。将它们组合起来我们就可以知道AbstractFactory表示“抽象工厂”的意思。
抽象工厂的工作是将“抽象零件”组装为“抽象产品”。
我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装成为产品。
包 | 名字 | 说明 |
---|---|---|
factory | Factory | 表示抽象工厂的类(制作Link,Tray,Page) |
factory | Item | 方便统一处理Link和Tray的类 |
factory | Link | 抽象零件:表示HTML的链接的类 |
factory | Tray | 抽象零件: 表示含有Link和Tray的类 |
factory | Page | 抽象零件: 表示HTML页面的类 |
无名 | Test | 测试程序行为的类 |
listfactory | ListFactory | 表示具体工厂的类(制作ListLink,ListTray等) |
listfactory | ListLink | 具体零件:表示HTML的链接的类 |
listfactory | ListTray | 具体零件:表示含有Link和Tray的类 |
listfactory | ListPage | 具体零件:表示HTML页面的类 |
factory包
包含抽象工厂、零件、产品的包。
Item
Item类是Link类和Tray类的父类(Item有“项目”的意思)。这样,Link类和Tray类就具有可替换行了。
caption字段标识项目的“标题”。
makeHTML方法是抽象方法,需要子类来实现这个方法。该方法会返回HTML文件的内容(需要子类去实现)。
package abstractfactory.factory;
/**
* @author wenei
* @date 2021-05-23 19:50
*/
public abstract class Item {
/**
* 标题
*/
protected String caption;
public Item(String caption) {
this.caption = caption;
}
public abstract String makeHTML();
}
Link
Link类是抽象的表示HTML的超链接的类。
url字段中保存的是超链接所指向的地址。
Link类并没有实现父类的makeHTML抽象方法,所以其也是抽象类。
package abstractfactory.factory;
import abstractfactory.factory.Item;
/**
* @author wenei
* @date 2021-05-23 19:51
*/
public abstract class Link extends Item {
protected String url;
public Link(String caption, String url) {
super(caption);
this.url = url;
}
}
Tray
Tray表示的是一个含有多个Link类和Tray类的容器。
Tray类使用的add方法将Link类和Tray类集合在一起。
package abstractfactory.factory;
import java.util.ArrayList;
/**
* @author wenei
* @date 2021-05-23 19:52
*/
public abstract class Tray extends Item {
protected ArrayList<Item> tray = new ArrayList<>();
public Tray(String caption) {
super(caption);
}
public void add(Item item) {
tray.add(item);
}
}
Page
Page类是抽象地表示HTML页面的类。
如果将Link和Tray比喻成抽象的“零件”,那么Page类就是抽象的“产品”。
package abstractfactory.factory;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
/**
* @author wenei
* @date 2021-05-23 19:55
*/
public abstract class Page {
protected String title;
protected String author;
protected ArrayList<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 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 String makeHTML();
}
Factory
Factory是生成具体工厂实例的类。
虽然getFactory方法生成的是具体工厂的实例,但是返回值的类型是抽象工厂类型。
createLink、createTray、createPage等方法是用于在抽象工厂中生成零件和产品的方法。
package abstractfactory.factory;
/**
* @author wenei
* @date 2021-05-23 20:01
*/
public abstract class Factory {
public static Factory getFactory(Class<?> clazz) {
Factory factory = null;
try {
factory = (Factory) clazz.newInstance();
} catch (IllegalAccessException | InstantiationException 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);
}
listfactory包
具体的抽象类实现的包。
ListLink
ListLink类是Link类的子类。
package abstractfactory.listfactory;
import abstractfactory.factory.Link;
/**
* @author wenei
* @date 2021-05-23 20:08
*/
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";
}
}
LinkTray
package abstractfactory.listfactory;
import abstractfactory.factory.Item;
import abstractfactory.factory.Tray;
import java.util.Iterator;
/**
* @author wenei
* @date 2021-05-23 20:10
*/
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");
// 遍历Tray中的所有组件
for (Item item : tray) {
buffer.append(item.makeHTML());
}
buffer.append("</ul>\n");
buffer.append("</li>\n");
return buffer.toString();
}
}
ListPage
package abstractfactory.listfactory;
import abstractfactory.factory.Item;
import abstractfactory.factory.Page;
import java.util.Iterator;
/**
* @author wenei
* @date 2021-05-24 11:31
*/
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>");
buffer.append("<hl>" + title + "</hl>\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();
}
}
ListFactory
package abstractfactory.listfactory;
import abstractfactory.factory.Factory;
import abstractfactory.factory.Link;
import abstractfactory.factory.Page;
import abstractfactory.factory.Tray;
/**
* @author wenei
* @date 2021-05-24 11:36
*/
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);
}
}
测试类Test
Main类使用抽象工厂生产零件并将零件组装成产品。
该类并没有使用任何具体零件、产品和工厂。
package abstractfactory;
import abstractfactory.factory.Factory;
import abstractfactory.listfactory.ListFactory;
import abstractfactory.factory.Link;
import abstractfactory.factory.Page;
import abstractfactory.factory.Tray;
/**
* @author wenei
* @date 2021-05-24 11:36
*/
public class Test {
public static void main(String[] args) {
Factory factory = Factory.getFactory(ListFactory.class);
Link people = factory.createLink("人民日报", "http://www.people.com.cn/");
Link gmw = factory.createLink("光明日报", "http://www.gmw.cn/");
Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");
Link jp_yahoo = factory.createLink("Yahoo!Japan", "http://www.yahoo.co.jp/");
// 日报类链接
Tray traynews = factory.createTray("日报");
traynews.add(people);
traynews.add(gmw);
// 搜索类链接
Tray trayyahoo = factory.createTray("Yahoo!");
trayyahoo.add(us_yahoo);
trayyahoo.add(jp_yahoo);
// 创建一个页面
Page page = factory.createPage("LinkPage", "浩浩");
// 添加tray
page.add(traynews);
page.add(trayyahoo);
// 将页面输出
page.output();
}
}
相关角色
-
AbstractProduct(抽象产品)
AbstractProduct角色负责定义AbstractFactory角色所生成的抽象零件和产品的接口(API)。在实例程序中,由Link类、Tray类和Page类扮演此角色 -
AbstractFactory(抽象工厂)
AbstractFactory角色负责定义用于生成抽象产品的接口(API)。在实例程序中,由Factory类扮演此角色。 -
Client(委托者)
Client仅会调用AbstractFactory角色和AbstractProduct角色的接口(API)来进行工作,对于具体的零件、产品和工厂一无所知。