创建型设计模式详解 - 4.3: 抽象工厂模式实操解析
4.3.1 抽象工厂模式介绍
抽象工厂模式比工厂方法模式的抽象程度更高. 在工厂方法模式中每一个具体工厂只需要生产一种具体产品,但是在抽象工厂模式中一个具体工厂可以生产一组相关的具体产品,这样一组产品被称为产品族.产品族中的每一个产品都分属于某一个产品继承等级结构.
1) 产品等级结构与产品族
为了更好的理解抽象工厂, 我们这里先引入两个概念:
-
产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
-
产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
在上图中,每一个具体工厂可以生产属于一个产品族的所有产品,例如海尔工厂生产海尔电视机、海尔空调和海尔冰箱,所生产的产品又位于不同的产品等级结构中. 如果使用工厂方法模式,上图所示的结构需要提供9个具体工厂,而使用抽象工厂模式只需要提供3个具体工厂,极大减少了系统中类的个数.
2) 抽象工厂模式概述
抽象工厂模式(Abstract Factory Pattern) 原始定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式为创建一组对象提供了解决方案.与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,而是负责创建一个产品族.如下图:
4.3.2 抽象工厂模式原理
在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法,用于产生多种不同类型的产品.这些产品构成了一个产品族.
抽象工厂模式的主要角色如下:
- 抽象工厂(Abstract Factory):它声明了一种用于创建一族产品的方法,每一个方法对应一种产品.
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建.
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
4.3.3 抽象工厂模式实现
抽象工厂
/**
* 抽象工厂: 在一个抽象工厂中可以声明多个工厂方法,用于创建不同类型的产品
* @author spikeCong
* @date 2022/9/15
**/
public interface AppliancesFactory {
AbstractTV createTV();
AbstractFreezer createFreezer();
}
具体工厂: 每一个具体工厂方法,可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族.
public class HairFactory implements AppliancesFactory {
@Override
public AbstractTV createTV() {
return new HairTV();
}
@Override
public AbstractFreezer createFreezer() {
return new HairFreezer();
}
}
public class HisenseFactory implements AppliancesFactory {
@Override
public AbstractTV createTV() {
return new HisenseTV();
}
@Override
public AbstractFreezer createFreezer() {
return new HisenseFreezer();
}
}
抽象产品
public interface AbstractFreezer {}
public interface AbstractTV {}
具体产品
public class HairFreezer implements AbstractFreezer {}
public class HisenseFreezer implements AbstractFreezer {}
public class HairTV implements AbstractTV {}
public class HisenseTV implements AbstractTV {}
客户端
public class Client {
private AbstractTV tv;
private AbstractFreezer freezer;
public Client(AppliancesFactory factory){
//在客户端看来就是使用抽象工厂来生产家电
this.tv = factory.createTV();
this.freezer = factory.createFreezer();
}
public AbstractTV getTv() {
return tv;
}
public void setTv(AbstractTV tv) {
this.tv = tv;
}
public AbstractFreezer getFreezer() {
return freezer;
}
public void setFreezer(AbstractFreezer freezer) {
this.freezer = freezer;
}
public static void main(String[] args) {
Client client = new Client(new HisenseFactory());
AbstractTV tv = client.getTv();
System.out.println(tv);
AbstractFreezer freezer = client.getFreezer();
System.out.println(freezer);
}
}
4.3.4 抽象工厂模式总结
从上面代码实现中我们可以看出,抽象工厂模式向使用(客户)方隐藏了下列变化:
- 程序所支持的实例集合(具体工厂)的数目;
- 当前是使用的实例集合中的哪一个实例;
- 在任意给定时刻被实例化的具体类型;
所以说,在理解抽象工厂模式原理时,你一定要牢牢记住“如何找到某一个类产品的正确共性功能”这个重点。
抽象工厂模式优点
-
对于不同产品系列有比较多共性特征时,可以使用抽象工厂模式,有助于提升组件的复用性.
-
当需要提升代码的扩展性并降低维护成本时,把对象的创建和使用过程分开,能有效地将代码统一到一个级别上
- 解决跨平台带来的兼容性问题
抽象工厂模式缺点
增加新的产品等级结构麻烦,需要对原有结构进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大不变,违背了开闭原则.