专题:Swift版:设计模式----简单工厂模式、工厂方法模式、抽象工厂模式以及三者的区别(奥利给)

1,321 阅读6分钟

今天我们所说的这种模式都是创建型设计模式

简单工厂模式

简单工厂模式实现了生成产品类的代码跟客户端代码的分离,在工厂类中你可以添加所需的生成产品的逻辑代码

简单工厂模式Swift代码

///简单工厂模式
/// 定义枚举来标识我们需要获得的汽车种类
enum CarType {
    case bmw
    case benz
    // TODO: 如果客户现在需要奥迪汽车,新增奥迪种类
    case audi
}

/// 产品需要实现的协议
protocol CarProduct {
    func carProduct()
}

/// 宝马汽车
struct BmwCar: CarProduct {
    func carProduct() {
        print("宝马汽车")
    }
}


/// 奔驰汽车
struct BenzCar: CarProduct {
    
    func carProduct() {
        print("奔驰汽车")
    }
}

// TODO: 新增奥迪汽车
struct AudiCar: CarProduct {
    func carProduct() {
        print("奥迪汽车")
    }
}



/// 汽车工厂生产汽车
struct CarFactory {
    
    /// 根据客户端传入的type类型来决定创建什么类型的汽车
    /// - Parameter type: 汽车类型
    static func productCar(type: CarType) {
        switch type {
        case .benz:
            let benz = BenzCar()
            benz.carProduct()
        case .bmw:
            let bmw = BmwCar()
            bmw.carProduct()
        case .audi:
        // TODO: 如果客户现在需要奥迪汽车,那么我们就要修改内部代码,新增switch循环判断,如果你的逻辑很复杂的话,这个就不很友好了
            let audi = AudiCar()
            audi.carProduct()
            
        }
    }
}

///客户端使用
///简单工厂模式
    CarFactory.productCar(type: .bmw)
///打印: 宝马汽车

这个简单模式相信大家一看就懂,肯定也能看出来这种模式的缺陷

缺点

  • 违背了开放-封闭原则,前面我们已经有了宝马和奔驰,那么接下来客户如果需要奥迪汽车,那我们只能去修改内部func productCar(type: CarType)方法,进行switch判断,如果你的逻辑很多,是不是又要改很多东西?这显然不太适合。对于这个问题,我们的工厂方法模式就可以解决这个问题。下面我们来介绍工厂方法模式。

工厂方法模式

定义

  • 工厂方法是一种创建型设计模式,其在父类中提供一个创建对象的接口,允许子类决定实例化对象的类型。

适用性

  • 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
  • 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
  • 如果你希望复用现有对象来节省系统资源,而不是每次都重新创建对象,可使用工厂方法。

优点

  • 你可以避免创建者和具体产品之间的紧密耦合。

  • 单一职责原则。你可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护

  • 开闭原则。无需更改现有客户端代码,你就可以在程序中引入新的产品类型。

缺点

  • 应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂。最好的情况是将该模式引入创建者类的现有层次结构中。

工厂方法模式Swift代码:

///工厂模式
protocol FactoryCar {
    func creatProductCar()
}

/// 宝马工厂
struct BmwFactory: FactoryCar {
    func creatProductCar() {
        let bmw = BmwFactoryCar()
        bmw.carProduct()
    }
}

/// 奔驰工厂
struct BenzFactory: FactoryCar {
    func creatProductCar() {
        let benz = BenzFactoryCar()
        benz.carProduct()
    }
}

//TODO:  新增奥迪工厂
struct AudiFactory: FactoryCar {
    func creatProductCar() {
        let audi = AudiFactoryCar()
        audi.carProduct()
    }
}

/// 产品需要实现的协议
protocol CarFactoryProduct {
    func carProduct()
}

/// 生产宝马汽车
struct BmwFactoryCar: CarFactoryProduct {
    func carProduct() {
        print("宝马汽车")
    }
}


/// 生产奔驰汽车
struct BenzFactoryCar: CarFactoryProduct {
    
    func carProduct() {
        print("奔驰汽车")
    }
}

//TODO:  新增生产奥迪汽车
struct AudiFactoryCar: CarFactoryProduct {
    func carProduct() {
        print("奥迪汽车")
    }
}



/// 定义枚举来标识我们需要获得的汽车种类
enum CarFactoryType {
    case bmw
    case benz
    //TODO:  新增奥迪系列
    case audi
}


/// 外部使用
struct CarFactoryMethod {
    /// 根据客户端传入的type类型来决定创建什么类型的汽车
    /// - Parameter type: 汽车类型
    static func productCar(type: CarFactoryType) {
        switch type {
        case .benz:
            let benz = BenzFactory()
            benz.creatProductCar()
        case .bmw:
            let bmw = BmwFactory()
            bmw.creatProductCar()
        case .audi:
            //TODO:  新增获取奥迪汽车
            let audi = AudiFactory()
            audi.creatProductCar()
            
        }
    }
}

抽象工厂模式

定义

  • 抽象工厂是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。

适用性

  • 如果代码需要与多个不同系列的相关产品交互,但是由于无法提前获取相关信息,或者出于对未来扩展性的考虑,你不希望代码基于产品的具体类进行构建,在这种情况下,你可以使用抽象工厂。
  • 如果你有一个基于一组抽象方法的类,且其主要功能因此变得不明确,那么在这种情况下可以考虑使用抽象工厂模式。

优点

  • 你可以确保同一工厂生成的产品相互匹配。

  • 你可以避免客户端和具体产品代码的耦合。

  • 单一职责原则,你可以将产品生成代码抽取到同一位置, 使得代码易于维护。

  • 开闭原则,向应用程序中引入新产品变体时, 你无需修改客户端代码。

缺点

  • 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。

抽象工厂模式Swift代码:

///抽象工厂模式 生产统一的种类 如:宝马汽车我需要宝马车标,奔驰需要奔驰车标,不要搞成宝马车贴成了奔驰车标,那就搞笑了

protocol AudoLogo {
    func audoLogoMethod()
}

struct BmwAudoLogo: AudoLogo {
    func audoLogoMethod() {
        print("宝马车标")
    }
}

struct BenzAudoLogo: AudoLogo {
    func audoLogoMethod() {
        print("奔驰车标")
    }
}

struct AudiAudoLogo: AudoLogo {
    func audoLogoMethod() {
        print("奥迪车标")
    }
}

protocol FactoryAudo {
    func ceratLogo() -> AudoLogo
}


protocol FactoryACar {
    func creatProductCar()
    func creatLogo()
    
}

/// 宝马工厂
struct BmwAFactory: FactoryACar {
    func creatLogo() {
        let bmw = BmwAudoLogo()
        bmw.audoLogoMethod()
    }
    
    func creatProductCar() {
        let bmw = BmwAFactoryCar()
        bmw.carProduct()
    }
}

/// 奔驰工厂
struct BenzAFactory: FactoryACar {
    func creatLogo() {
        let benz = BmwAudoLogo()
        benz.audoLogoMethod()
    }
    
    func creatProductCar() {
        let benz = BenzAFactoryCar()
        benz.carProduct()
    }
}

//TODO:  新增奥迪工厂
struct AudiAFactory: FactoryACar {
    func creatLogo() {
        let audi = AudiAudoLogo()
        audi.audoLogoMethod()
    }
    
    func creatProductCar() {
        let audi = AudiAFactoryCar()
        audi.carProduct()
    }
}

/// 产品需要实现的协议
protocol CarAFactoryProduct {
    func carProduct()
}

/// 生产宝马汽车
struct BmwAFactoryCar: CarAFactoryProduct {
    func carProduct() {
        print("宝马汽车")
    }
}


/// 生产奔驰汽车
struct BenzAFactoryCar: CarAFactoryProduct {
    
    func carProduct() {
        print("奔驰汽车")
    }
}

//TODO:  新增生产奥迪汽车
struct AudiAFactoryCar: CarAFactoryProduct {
    func carProduct() {
        print("奥迪汽车")
    }
}



/// 定义枚举来标识我们需要获得的汽车种类
enum CarAFactoryType {
    case bmw
    case benz
    //TODO:  新增奥迪系列
    case audi
}


/// 外部使用
struct CarAFactoryMethod {
    /// 根据客户端传入的type类型来决定创建什么类型的汽车
    /// - Parameter type: 汽车类型
    static func productCar(type: CarAFactoryType) {
        switch type {
        case .benz:
            let benz = BenzAFactory()
            benz.creatProductCar()
            benz.creatLogo()
        case .bmw:
            let bmw = BmwAFactory()
            bmw.creatProductCar()
            bmw.creatLogo()
        case .audi:
            //TODO:  新增获取奥迪汽车
            let audi = AudiAFactory()
            audi.creatProductCar()
            audi.creatLogo()
            
        }
    }
}

///打印数据:
奥迪汽车
奥迪车标

  • 抽象工厂模式中我们可以定义实现不止一个协议,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。按照我的理解是:只要是同一个种类需要增加不同产品,都可以使用抽象模式,采用同一工厂去生产产品

Demo工程传送门

  • 文中如有问题,请大家指明一下,互相学习,互相进步(通过自己的理解来一步一步实现的,避免理解有误,还请大家监督,谢谢)

不管我们遇到什么困难,也不要怕,微笑着面对它,消除恐惧的最好办法就是面对恐惧,坚持,才是胜利,加油,奥利给!!