创建者模式-抽象工厂模式

126 阅读3分钟

抽象工厂模式

概念

是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

结构

抽象工厂模式的主要角色如下:

  • 抽象工厂 (Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂 (concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品 (Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品 (concreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

案例

现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是-一个产品等级,都是咖啡:提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。所以这个案例可以使用抽象工厂模式实现。

//咖啡类
class Coffee{
    func getName()->String{
        fatalError("Must Override")
    }
//    加糖
    func addSugar(){
        print("加糖")
    }
//    加奶
    func addMilk(){
        print("加奶")
    }
}
class AmericanCoffee:Coffee{
    override func getName() -> String {
        return "美式咖啡"
    }
}
class LatteCoffee:Coffee{
    override func getName() -> String {
        return "拿铁咖啡"
  
    }
}
//甜点抽象类
protocol Dessert{
    func show()
}
//提拉米苏
class Trimisu:Dessert {
    func show() {
        print("提拉米苏")
    }
}
//抹茶慕斯类
class MatchaMousse:Dessert{
    func show() {
        print("抹茶慕斯")
    }
}
​
//抽象工厂接口
protocol DessertFactory{
//    生产咖啡的功能
    func createCoffee()->Coffee
//    生产甜品的功能
    func createDesert()->Dessert
}
//美式风味的工厂 可以生产美式风味的咖啡和抹茶慕斯
class AmericanDessertFactory:DessertFactory{
    func createCoffee() -> Coffee {
        return AmericanCoffee()
    }
    func createDesert() -> Dessert {
        return MatchaMousse()
    }
}
​
//意大利风味的工厂 可以生产拿铁咖啡和提拉米苏
class ItalyDessertFactory:DessertFactory{
    func createCoffee() -> Coffee {
        return LatteCoffee()
    }
    func createDesert() -> Dessert {
        return Trimisu()
    }
}
​

测试代码

//创建意大利风味的甜品工厂
var factory = ItalyDessertFactory()
var coffee = factory.createCoffee()
var desert = factory.createDesert()
print(coffee.getName())
desert.show()
print("==============")
​
var factory1 = AmericanDessertFactory()
var coffee1 = factory.createCoffee()
var desert1 = factory.createDesert()
print(coffee1.getName())
desert1.show()
​

运行结果:

image-20220911105302961

如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他类。

优缺点

  • 优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  • 缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

使用场景

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

感谢黑马程序员课程