一、产品等级和产品族
为了更好的理解抽象工厂模式,引入了两个概念。
1,产品等级结构:产品等级结构即产品的继承结构。
2,产品族:在抽象工厂模式中,产品族是指有同一个工厂生产的位于不同产品等级结构中的一组产品。
举个例子:
产品等级结构:一个抽象类是电视机,其子类是海尔电视机,海信电视机,TCL电视机。抽象电视机与具体品牌的电视机之间构成了一个产品等级结构。
产品族:例如海尔电器工厂生产的海尔电视机,海尔冰箱,海尔电视机位于电视机产品等级结构中,海尔冰箱位于冰箱产品等级结构中,海尔电视机、海尔冰箱构成了一个产品族。
二、抽象工厂模式概述
定义:
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体的类。
三、抽象工厂模式结构与实现
3.1 抽象工厂模式结构
抽象工厂模式包含以下4个角色:
- AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对于一种产品。
- ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品的等级结构中。
- AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
- ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
3.2 抽象工厂模式实现
抽象产品代码:
public interface Button {
void display();
}
public interface Text {
void display();
}
具体产品代码:
public class LinuxButton implements Button{
@Override
public void display() {
System.out.println("Linux button");
}
}
public class UNIXButton implements Button{
@Override
public void display() {
System.out.println("UNIX button");
}
}
public class WindowsButton implements Button{
@Override
public void display() {
System.out.println("Windows button");
}
}
public class LinuxText implements Text{
@Override
public void display() {
System.out.println("Linux text");
}
}
public class UNIXText implements Text{
@Override
public void display() {
System.out.println("UNIX text");
}
}
public class WindowsText implements Text{
@Override
public void display() {
System.out.println("Windows text");
}
}
抽象工厂代码:
public interface OSFactory {
Button createButton();
Text createText();
}
具体工厂代码:
public class LinuxOSFactory implements OSFactory{
@Override
public Button createButton() {
return new LinuxButton();
}
@Override
public Text createText() {
return new LinuxText();
}
}
public class WindowsOSFactory implements OSFactory{
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Text createText() {
return new WindowsText();
}
}
public class UNIXOSFactory implements OSFactory{
@Override
public Button createButton() {
return new UNIXButton();
}
@Override
public Text createText() {
return new UNIXText();
}
}
<?xml version="1.0" encoding="UTF-16" ?>
<config>
<className>creationalpatterns.abstractfactorypattern.LinuxOSFactory</className>
</config>
工具类代码:
public class XMLUtil {
//该方法用于从XML配置文件提取具体类的类名,并返回一个实例对象
public static Object getBean() {
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dFactory.newDocumentBuilder();
Document document = documentBuilder.parse("src/resources/abstractfactoryconfig.xml");
NodeList nodeList = document.getElementsByTagName("className");
Node firstChild = nodeList.item(0).getFirstChild();
String cName = firstChild.getNodeValue();
Class<?> c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
} catch (Exception e) {
e.printstacktrace();
return null;
}
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 现有为不同操作系统展示不同组件的内容。
* 有2个产品等级结构,分别是Button和Text;
* 有3个产品族,即UNIX产品族,Linux产品族,Windows产品族。
* 使用抽象工厂模式来设计实现。
*/
OSFactory osFactory;
Button button;
Text text;
osFactory = (OSFactory)XMLUtil.getBean();
button = osFactory.createButton();
text = osFactory.createText();
button.display();
text.display();
}
}
四、抽象工厂模式优缺点和适用环境
4.1 抽象工厂模式优点
- 隔离了具体类的生成,使得客户端并不需要知道什么被创建;
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象;
- 增加新的产品族很方便,无袖修改已有系统,符合开闭原则;
4.2 抽象工厂模式缺点
4.3 抽象工厂模式适用环境
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节;
- 系统中有多于一个的产品族,而每次只使用其中某一产品族;
- 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来;
- 产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
五、开闭原则的倾斜性
抽象工厂模式以一种倾斜的方式来满足开闭原则。对于增加新的产品族,抽象工厂模式很好地支持了开闭原则;对于增加新的产品等级结构,需要修改所有的工厂角色,违背了开闭原则。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git
原文地址:https://www.jb51.cc/wenti/3287079.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。