概念 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个接口用于创建相关或依赖对象的家族,而不需要指定具体类
抽象工厂模式通过引入抽象工厂接口和具体工厂实现类来实现这一点
在抽象工厂模式中,存在两个关键角色:抽象工厂(Abstract Factory)和具体工厂(Concrete Factory)
抽象工厂定义了创建产品家族的方法,而具体工厂实现了这些方法,用于创建具体的产品对象
每个产品家族都有一组相互关联的产品,而每个具体产品由具体工厂类创建
抽象工厂接口(Abstract Factory Interface)
定义了一组创建产品的抽象方法,客户端通过调用这些抽象方法来创建产品
具体工厂类(Concrete Factory)
实现了抽象工厂接口,负责创建一组相关的产品
抽象产品(Abstract Product)
定义了一组产品的抽象接口或抽象类
具体产品(Concrete Product)
实现了抽象产品接口或抽象类的具体类
抽象工厂模式的核心思想是通过引入抽象工厂来创建产品家族,使得客户端代码可以与具体的产品类解耦,从而使得系统更加灵活,能够更容易地应对需求变化
举个简单的例子,考虑一个跨平台图形界面工具包
可以有不同类型的界面元素(如按钮、文本框等),也可以有不同的主题(如浅色主题、深色主题等)
使用抽象工厂模式,可以将界面元素的类型和主题分离开来,使得可以很容易地添加新的界面元素类型或主题,而不需要修改已有的代码
实现条件
存在一组相关或相互依赖的产品
抽象工厂模式适用于需要创建一组相关或相互依赖的产品的情况
这些产品通常是属于同一产品族或产品等级结构的,它们之间有一定的关联性或依赖关系
需求频繁变化的系统
如果系统中的产品族经常需要变化,或者需要支持多个不同的产品族,并且这些产品族的组成结构可能不断变化,那么抽象工厂模式可以提供一种灵活的方式来管理这些变化
客户端代码不依赖于具体产品类
抽象工厂模式要求客户端代码不依赖于具体的产品类,而是通过抽象工厂接口来创建产品,从而实现了客户端代码与具体产品类的解耦
需要一致性的创建过程
如果系统中的产品需要遵循一致的创建过程,并且这些产品的创建过程可能随着产品族的变化而变化,那么抽象工厂模式可以提供一种统一的方式来管理这些创建过程
需求层次结构化
抽象工厂模式适用于系统中的产品具有层次结构的情况
例如,产品族之间可能存在一定的层次结构关系,或者产品族内部的产品也可能具有层次结构
优点
隔离具体类的生成
使用者不需要知道具体的实现细节,只需关心接口和返回的抽象产品
易于交换产品系列
由于具体的工厂类在一个应用中只需要在初始化的时候出现一次,这使得改变一个应用的具体实现变得相对容易
促进一致性
当产品构成一系列的时候,确保客户端始终只使用同一个产品系列中的对象
缺点
实现方式 使用ES6的Class创建最基础的抽象工厂接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 class GenericAbstractFactoryPattern { createCar () { throw new Error ('不能调用抽象方法,请自己实现' ) } createEngine () { throw new Error ('不能调用抽象方法,请自己实现' ) } createChassis () { throw new Error ('不能调用抽象方法,请自己实现' ) } createBody () { throw new Error ('不能调用抽象方法,请自己实现' ) } createElectrical () { throw new Error ('不能调用抽象方法,请自己实现' ) } createTransmission () { throw new Error ('不能调用抽象方法,请自己实现' ) } createType () { throw new Error ('不能调用抽象方法,请自己实现' ) } } export default GenericAbstractFactoryPattern
新建汽车基础类,让车辆继承父类的一些基本方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 export class Car { constructor (options = {} ) { Object .assign (this , options || {}) } drive ( ) { console .log ('the name of the car that s driving right now is' + this .name ) } stopDriving () { console .log ('the name of the car that stopped' + this .name ) } } export class Chassis { constructor (options = {} ) { Object .assign (this , options || {}) } assemble ( ) { console .log (`The chassis made of ${this .material} and type ${this .type} is being assembled.` ); } } export class Engine { constructor (options = {} ) { Object .assign (this , options || {}) } start ( ) { console .log (`The ${this .type} engine with ${this .horsepower} horsepower is starting.` ); } }
新建子类进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 import GenericAbstractFactoryPattern from '../AbstractFactoryPattern' import { Car , Chassis , Engine } from './BasicCarClass' class AudiCar extends Car { constructor (options ) { super ({ name : 'Audi' , lights : 'LED' , color : 'Black' , ...options }) } } class AudiEngine extends Engine { constructor (options ) { super ({ type : 'Audi Engine' , horsepower : '300' , ...options }) } } class AudiChassis extends Chassis { constructor (options ) { super ({ material : 'Aluminum' , type : 'Audi Chassis' , ...options }) } } class AudiSubclass extends GenericAbstractFactoryPattern { constructor (options ) { super () this .options = options } createCar () { if (this .options && this .options .carInfo ) { return new AudiCar (this .options .carInfo ) } else { throw new Error ('未提供正确的汽车信息' ) } } createEngine () { return new AudiEngine () } createChassis () { return new AudiChassis () } } export default AudiSubclass
然后在代码里面使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import AudiSubclass from './AudiSubclass' const options = { carInfo : { name : 'Audi A4' , lights : 'LED' , color : 'Black' } } const audiFactory = new AudiSubclass (options)try { const myAudiCar = audiFactory.createCar () myAudiCar.drive () } catch (error) { console .error (error.message ) }
代码示例是一个抽象工厂模式的实现,它定义了创建汽车及其组件的通用接口。这个模式用于创建一系列相关或依赖对象的家族,而无需指定其具体类
抽象工厂类(GenericAbstractFactoryPattern
)
这个类定义了一系列创建不同汽车组件的抽象方法,这是抽象工厂模式的典型实现,它允许子类来具体实现这些方法
具体工厂类(AudiSubclass
)
这个类继承自抽象工厂类,并实现了创建奥迪汽车和相关组件的具体方法
这里您只展示了createCar
方法的实现,其他组件的创建方法(如createEngine
和createChassis
)还没有具体的实现细节
具体产品类(AudiCar
)
这是一个具体的产品类,它继承自Car
类,并在构造函数中初始化了奥迪汽车的属性
Car
类
这个类定义了汽车的基础属性和方法,如drive
和stopDriving
场景 抽象工厂模式适用于以下情况:
系统要求产品族内的对象之间存在相互关联或依赖关系
系统需要独立于其产品的创建、组合和表示时
源代码