设计模式 -- 抽象工厂模式

2023-11-22 09:23:02 浏览数 (1)

表述 (创建型模式)

提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类

抽象工厂模式和工厂方法模式很相似,是三种工厂模式中最抽象的一种设计模式。抽象工厂模式中定义了抽象工厂类,抽象工厂类中定义了每个系列的抽象类创建的方法,每个工厂子类都对应着一个系列,工厂子类通过重写这些方法来实例化当前系列的抽象子类

抽象工厂模式类图

抽象工厂模式类图

  • 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新类,所以需要在适合的业务场景使用这种模式,否则会适得其反

0 人点赞