表述 (创建型模式)
提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类
抽象工厂模式和工厂方法模式很相似,是三种工厂模式中最抽象的一种设计模式。抽象工厂模式中定义了抽象工厂类,抽象工厂类中定义了每个系列的抽象类创建的方法,每个工厂子类都对应着一个系列,工厂子类通过重写这些方法来实例化当前系列的抽象子类
抽象工厂模式类图
抽象工厂模式类图
- AbstractFactory(抽象工厂接口):负责创建抽象类
- ConcreteFactory1和ConcreteFactory2(具体的工厂):继承自抽象工厂类,重写父类定义的对应方法,直接在客户端的使用下创建对应的抽象子类
- AbstractProductA和AbstractProductB(抽象产品):定义当前类型抽象子类的操作,子类继承父类完成具体的操作
- ProductA1、ProductA2、ProductB1和ProductB2(具体的产品):抽象子类,继承自对应的抽象类,是客户最终需要的产品,实现抽象类的接口,定制自己实现的逻辑
优点
- 切换产品变得容易
- 封装性,具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中
使用场景
- 类可以让其子类决定在运行期具体实例化的对象
- 封装一组相互关联的类的创建
- 从产品角度讲,如果系统有多于一个的产品族,而系统只消费其中的某一产品;一个系统不应该依赖于产品实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的
示例
需求V1:现有俩个系列手机iPhone和xiaomi,它们分别有这打电话、发信息这俩个功能
iPhone 和 xiaomi 属于不同的系列,所以,是俩个不同的工厂子类,俩者都有打电话、发信息功能,每个功能就是一个类型,每个类型就是一个抽象类,因此,iPhone 的打电话抽象子类对应 xiaomi 打电话抽象子类,这俩个抽象子类都属于同一类型,继承同一个抽象类,分别被不同系列的工厂子类创建,在抽象设计模式中,不同系列相同类型的抽象子类都是一一对应的
抽象类和抽象子类:
代码语言:javascript复制//定义发信息抽象类
class SendMessage {
func sendMessage() {
}
}
//定义打电话抽象类
class CallPhone {
func callPhone() {
}
}
//抽象子类分别继承不同类型的抽象类,并实现不同系列的持久化代码
class iPhoneSendMessage : SendMessage {
override func sendMessage() {
print("iphone 发信息")
}
}
class XiaomiSendMessage : SendMessage {
override func sendMessage() {
print("xiaomi 发信息")
}
}
class iPhoneCallPhone : CallPhone {
override func callPhone() {
print("iphone 打电话")
}
}
class XiaomiCallPhone : CallPhone {
override func callPhone() {
print("xiaomi 打电话")
}
}
抽象工厂类和工厂子类:
代码语言:javascript复制//定义了俩个抽象接口用来实例化不同类型的抽象类
class PhoneFactory {
func createCallPhone() -> CallPhone {
return CallPhone()
}
func createSendMessage() -> SendMessage {
return SendMessage()
}
}
//实现了不同系列的抽象子类实例化
class iPhoneFactory : PhoneFactory {
override func createCallPhone() -> CallPhone {
return iPhoneCallPhone()
}
override func createSendMessage() -> SendMessage {
return iPhoneSendMessage()
}
}
//实现了不同系列的抽象子类实例化
class XiaomiFactory : PhoneFactory {
override func createCallPhone() -> CallPhone {
return XiaomiCallPhone()
}
override func createSendMessage() -> SendMessage {
return XiaomiSendMessage()
}
}
客户端调用:
代码语言:javascript复制let iPhoneFac = iPhoneFactory()
let iphoneCall = iPhoneFac.createCallPhone()
iphoneCall.callPhone()
let iphoneSend = iPhoneFac.createSendMessage()
iphoneSend.sendMessage()
let xiaomiFac = XiaomiFactory()
let xiaomiCall = xiaomiFac.createCallPhone()
xiaomiCall.callPhone()
let xiaomiSend = xiaomiFac.createSendMessage()
xiaomiSend.sendMessage()
需求V2:假设在原有需求上又加入了一个功能,俩个系列的手机都有打游戏的功能
根据需求V2,需要增加了打游戏,那么就是增加了一个类型,所以我们需要新增一个抽象类,同时需要更改抽象工厂和工厂子类
新增抽象类:
代码语言:javascript复制class PlayGame {
func playGame() {
}
}
class iPhonePlayGame : PlayGame {
override func playGame() {
print("iphone 打游戏")
}
}
class XiaomiPlayGame : PlayGame {
override func playGame() {
print("xiaomi 打游戏")
}
}
修改后的抽象工厂和工厂子类:
代码语言:javascript复制//定义了俩个抽象接口用来实例化不同类型的抽象类
class PhoneFactory {
func createCallPhone() -> CallPhone {
return CallPhone()
}
func createSendMessage() -> SendMessage {
return SendMessage()
}
func createPlaygame() -> PlayGame {
return PlayGame()
}
}
//实现了不同系列的抽象子类实例化
class iPhoneFactory : PhoneFactory {
override func createCallPhone() -> CallPhone {
return iPhoneCallPhone()
}
override func createSendMessage() -> SendMessage {
return iPhoneSendMessage()
}
override func createPlaygame() -> PlayGame {
return iPhonePlayGame()
}
}
//实现了不同系列的抽象子类实例化
class XiaomiFactory : PhoneFactory {
override func createCallPhone() -> CallPhone {
return XiaomiCallPhone()
}
override func createSendMessage() -> SendMessage {
return XiaomiSendMessage()
}
override func createPlaygame() -> PlayGame {
return XiaomiPlayGame()
}
}
客户端调用:
代码语言:javascript复制let iPhoneFac = iPhoneFactory()
let iphonePaly = iPhoneFac.createPlaygame()
iphonePaly.playGame()
let xiaomiFac = XiaomiFactory()
let xiaomiPlay = xiaomiFac.createPlaygame()
xiaomiPlay.playGame()
需求V3: 假设在原有需求上又加入了一个新款手机OPPO,并且它支持打电话、发信息、打游戏的功能
根据需求V3,需要分别继承三个原来的抽象类,新建三个抽象子类,因为加入的是一个新的系列,所以还需要新增一个工厂子类,原抽象工厂保持不变
新增抽象子类:
代码语言:javascript复制class OppoCallPhone : CallPhone {
override func callPhone() {
print("oppo 打电话")
}
}
class OppoSendMessage : SendMessage {
override func sendMessage() {
print("oppo 发信息")
}
}
class OppoPlayGame : PlayGame {
override func playGame() {
print("oppo 打游戏")
}
}
新增工厂子类:
代码语言:javascript复制class OppoFactory : PhoneFactory {
override func createCallPhone() -> CallPhone {
return OppoCallPhone()
}
override func createSendMessage() -> SendMessage {
return OppoSendMessage()
}
override func createPlaygame() -> PlayGame {
return OppoPlayGame()
}
}
客户端调用:
代码语言:javascript复制let oppoFac = OppoFactory()
let oppoCall = oppoFac.createCallPhone()
oppoCall.callPhone()
let oppoSend = oppoFac.createSendMessage()
oppoSend.sendMessage()
let oppoPaly = oppoFac.createPlaygame()
oppoPaly.playGame()
可以看出在新加系列产品或新加功能类型的需求下,都违背开放-封闭原则,而且要增加2-3新类,所以需要在适合的业务场景使用这种模式,否则会适得其反