文章目录
一、简介
1.1 引入
为了更清晰地理解抽象工厂模式,首先引入两个概念
- 产品等级结构:产品等级结构表示产品的继承结构,同一产品等级表示的是同一类型的东西。如一个抽象类是手机,其子类有华为手机、小米手机。那么抽象父类手机和具体手机品牌之间形成了一个产品等级结构,而这些具体手机品牌属于同一个产品等级
- 产品族:由同一个工厂生产的,位于不同产品等级中的一组产品,也就是说,同一家工厂生产的不同产品属于同一个产品族。如华为公司生产的华为手机和华为电脑,他们属于不同的产品等级,但属于同一个产品族
1.2 定义
抽象工厂(AbstractFactory)模式的定义:提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式又称为Kit模式,属于对象创建型模式
1.3 抽象工厂模式与工厂方法模式的区别
- 工厂方法模式针对的是一个产品等级结构,一个具体工厂只能生产一个具体产品
- 抽象工厂模式可生产多个等级的产品,一个具体工厂可以生产多个不同产品等级结构中的产品 。
- 当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率
二、模式原理
2.1 模式组成
组成(角色) | 作用 |
---|---|
Product(抽象产品) | 一个抽象类或接口,用来描述产品的特性和功能,有多个抽象产品,这些抽象产品也可以有一个共同的抽象产品族类 |
ConcreteProduct(具体产品) | 具体产品类继承或实现Product抽象父类,它和具体工厂之间是多对一关系 |
AbstractFactory(抽象工厂) | 一个抽象类或接口,它包含多个创建产品的方法,可以创建多个不同等级的产品 |
ConcreteFactory(具体工厂) | 主要用来实现抽象工厂中的多个抽象方法,完成具体产品的创建 |
2.2 UML类图
三、实例
3.1 实例概况
- 背景:现有华为和小米两家工厂,两家工厂均能生产手机和电脑
- 目的:利用抽象工厂方法分别生成华为和小米两家的手机和电脑
3.2 步骤
- 步骤一:创建抽象产品类
//抽象产品父类Mobile
public abstract class Mobile {
public abstract void show();
}
//抽象产品父类Computer
public abstract class Computer {
public abstract void show();
}
- 步骤二:创建抽象工厂类
//抽象工厂父类
public abstract class AbstractFactory {
public abstract Mobile createMobile();
public abstract Computer createComputer();
}
- 步骤三:创建具体产品类
//创建抽象产品类Mobile的具体产品子类
public class MobileA extends Mobile {
public void show() {
System.out.println("华为公司生产出手机A");
}
}
public class MobileB extends Mobile{
public void show() {
System.out.println("小米公司生产出手机B");
}
}
//创建抽象产品类Computer的具体产品子类
public class ComputerA extends Computer{
public void show() {
System.out.println("华为公司生产出电脑A");
}
}
public class ComputerB extends Computer{
public void show() {
System.out.println("小米公司生产出电脑B");
}
}
- 步骤四:创建具体工厂类
//创建具体工厂类Huawei
public class Huawei extends AbstractFactory{
public Mobile createMobile() {
return new MobileA();
}
public Computer createComputer() {
return new ComputerA();
}
}
//创建具体工厂类Xiaomi
public class Xiaomi extends AbstractFactory{
public Mobile createMobile() {
return new MobileB();
}
public Computer createComputer() {
return new ComputerB();
}
}
- 步骤五:外部实例化具体的工厂类,创建不同的具体产品
//BusinessHall营业厅
public class BusinessHall {
public static void main(String[] args) {
//生成华为产品
AbstractFactory huawei = new Huawei();
huawei.createMobile().show();
huawei.createComputer().show();
System.out.println("-------------");
//生成小米产品
AbstractFactory xiaomi = new Xiaomi();
xiaomi.createMobile().show();
xiaomi.createComputer().show();
}
}
//结果
华为公司生产出手机A
华为公司生产出电脑A
-------------
小米公司生产出手机B
小米公司生产出电脑B
3.3 UML类图
四、优缺点
4.1 优点
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下:
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个工厂的产品组
- 对新的产品族满足“开闭原则”
4.2 缺点
- 抽象工厂角色中规定了所有可能被创建的产品集合,如果要添加新的产品对象,就必须要对抽象工厂父类进行扩展,那么所有的工厂类都需要进行修改。
- 开闭原则的倾斜性:对于新的产品族符合开-闭原则;对于新的产品种类不符合开-闭原则(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
五、应用场景
抽象工厂模式通常适用于以下场景:
- 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
- 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
- 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
六、模式的扩展
6.1 "开闭原则"的倾斜性
-
增加产品族:对于增加新的产品族,只需要增加一个新的具体工厂即可,不需要对已有代码进行修改
-
增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的具体工厂类和抽象工厂类,在所有的具体工厂类中都需要增加生产新产品的方法,不能很好地支持“开闭原则”。
抽象工厂模式的这种性质称为“开闭原则”的倾斜性,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,但不能为新的产品等级结构的增加提供这样的方便。
6.2 工厂模式的退化
- 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;
- 当工厂方法模式中抽象工厂类与具体工厂类合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。