# 抽象工厂模式
# 参考
# 定义
简单工厂、工厂方法模式都是用于同一类型对象的创建,比如冰箱厂只生产冰箱、空调厂只生产空调。
然而在实际生活中,许多工厂是综合性工厂,比如格力,既生产格力冰箱,也生产格力空调等等。
抽象工厂模式,就是访问者无需指定具体的产品类,就能够创建、获取同一系列、族群相关的产品,比如我要格力家电,那么格力工厂就会把格力冰箱、空调、电视等等给我。
抽象工厂模式与工厂方法模式的不同在于,工厂方法模式生产一种类型的产品,而抽象工厂模式用于生产多个属于同一系列的产品。
# 应用场景
代码中有多个不同系列的相关产品交互,由于无法提前获取客户端需要的系列,或者考虑到可扩展性,这种情况下可以使用抽象工厂模式。
比如:一个GUI应用,在windows和mac系统下都需要渲染button、dialog等组件,但是在不同的平台下组件的样式为了适应平台特性,都有所差异。
此时可以使用抽象工厂模式,提炼抽象工厂,以及不同平台下对应的工厂,来生产同一系列的产品。
# 实现、应用思路
给所有产品根据系列归类。
抽象工厂,提供、定义创建产品的通用接口。
具体工厂,实现抽象工厂的抽象方法,完成同系列具体产品的创建。
抽象产品(也可以是接口),定义了产品的具体规范,描述了产品的主要特性、功能。这是工厂模式的一大前提。
具体产品,实现了抽象产品定义的接口,由具体工厂来创建,与具体工厂是多对一的关系,一个工厂创建同一系列的多个产品。
# 优点
可以确保同一类型产品的生产,匹配。
新增产品或者新增工厂,修改、新增工厂即可,无需修改外部业务逻辑,满足开闭原则。
统一类的产品由同一工厂管理,满足单一责职原则。
# 缺点
- 引入了众多的类、接口,增加了系统的抽象度,可能会更加难以理解。
# 代码实例
// 抽象产品
interface IButton {
render(): void
}
interface IDialog {
render(): void
}
// 同系列的具体产品
class WinButton implements IButton {
render() {
console.log('render windows button.')
}
}
class WinDialog implements IDialog {
render() {
console.log('render windows dialog.')
}
}
// 同系列的具体产品
class MacButton implements IButton {
render() {
console.log('render mac button.')
}
}
class MacDialog implements IDialog {
render() {
console.log('render mac dialog.')
}
}
// 抽象工厂
abstract class GUIFactory {
abstract createButton(): IButton
abstract createDialog(): IDialog
render() {
this.createButton().render()
this.createDialog().render()
}
}
// 具体工厂
class WindowsFactory extends GUIFactory {
createButton(): WinButton {
return new WinButton()
}
createDialog(): WinDialog {
return new WinDialog()
}
}
class MacFactory extends GUIFactory {
createButton(): MacButton {
return new MacButton()
}
createDialog(): MacDialog {
return new MacDialog()
}
}
// windows平台下的GUI渲染
new WindowsFactory().render()
// mac平台下的GUI渲染
new MacFactory().render()