Swift - 抽象工厂模式

什么是抽象工厂模式

抽象工厂模式(Abstract Factory Pattern) 是一种比较常见的设计模式,其定义如下:Provide an interface for creating families of realted or dependent objects without specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类)

抽象:其实就是指定某一个接口的规范,具体点来说,也就是创建一个基类,基类遵守着某一套规范,但是具体的实现规则让子类来完成。当然指定接口的规范,我们也可以使用协议。

 

抽象工厂的通用类图

由上图可知,抽象工厂由一个产品抽象类(当然也可以是多个)、一个抽象工厂类、多个具体产品子类、多个具体工厂类组成。当多个产品抽象类中由相同类型的子类的时候,就可以使用抽象工厂模式,参与者的角色:

抽象工厂角色:负责创建抽象产品,指定需要的接口,任何在模式中创建对象的工厂都必须实现这个接口

具体工厂角色:实现抽象工厂接口的具体实现类,直接在客户端的使用下创建对应的产品实例。

抽象产品角色:工厂方法所创建产品对象的超类型,也就是产品对象共同的父类或者共同的接口

具体产品角色:是客户最终需要的产品,实现抽象产品的接口,定制自己实现的逻辑

 

 

抽象工厂通用源码类图

源码实现:

抽象工厂和抽象产品

// 抽象工厂
protocol AbstractCreator {
    // 创建产品A
    func createPdoructA() -> AbstractProductA
    // 创建产品B
    func createProductB() -> AbstractProductB
}

// 抽象产品类 A
class AbstractProductA {
    func doSomething() {}
}

// 抽象产品类 B
class AbstractProductB {
    func doSomething() {}
}

具体工厂

// 具体工厂
class Creator1: AbstractCreator {
    func createPdoructA() -> AbstractProductA {
        return ProductA1()
    }

    func createProductB() -> AbstractProductB {
        return ProductB1()
    }
}

class Creator2: AbstractCreator {
    func createPdoructA() -> AbstractProductA {
        return ProductA2()
    }

    func createProductB() -> AbstractProductB {
        return ProductB2()
    }
}

具体产品


// 具体产品A1
class ProductA1: AbstractProductA {
    override func doSomething() {
        print("create prodouct A1")
    }
}

// 具体产品 A2
class ProductA2: AbstractProductA {
    override func doSomething() {
        print("create prodouct A2")
    }
}

// 具体产品 B1
class ProductB1: AbstractProductB {
    override func doSomething() {
        print("create prodouct B1")
    }
}

// 具体产品 B2
class ProductB2: AbstractProductB {
    override func doSomething() {
        print("create prodouct B2")
    }
}

使用

  // 定义两个工厂
  let creator1 = Creator1()
  let creator2 = Creator2()

  // 产生A1对象
  let productA1 = creator1.createPdoructA()
  // 产生A2对象
   let productA2 = creator2.createPdoructA()

  // 产生B1对象
  let productB1 = creator1.createProductB()
  // 产生B2对象
  let productB2 = creator2.createProductB()

  // do task
  productA1.doSomething()
  productA2.doSomething()
  productB1.doSomething()
  productB2.doSomething()

 

抽象工厂模式的使用流程

1、创建抽象工厂类,提供对应抽象产品的创建方法

2、定义抽象产品类,指定所需的接口,由具体产品类实现接口

3、 实现具体工厂,并在具体工厂中创建具体产品

 

使用场景

1、类可以让其子类决定在运行期具体实例化的对象

2、封装一组相互关联的类的创建

3、从产品角度讲,如果系统有多于一个的产品族,而系统只消费其中的某一产品;一个系统不应该依赖于产品实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的

 

抽象工厂模式的优点

1、封装性,每个产品的实现类不是高层模块需要关心的,它只需要关注接口即可,它并不需要知道对象是如何创建出来的,只要知道工厂类是谁,我们就能创造出自己需要的对象。

2、切换产品变得容易

 

抽象工厂模式的缺点

抽象工厂模式的最大缺点就是产品族扩展非常困难。回顾前面的通用代码部分,如果要增加一个产品C,也就是说产品家族由原来的2个增加到3个,抽象类AbstractCreator要增加一个方法createProductC(),然后两个实现类也都需要修改,很显然需要改动的地方非常多,而且这严重违法了开闭原则。

 

抽象工厂模式和工厂方法模式

目的:都是创建对象而不让客户端知道返回了什么具体对象

工厂模式抽象工厂模式
创建一种产品创建一组相互依赖的产品
通过对象继承创建抽象产品通过对象组合创建抽象产品
子类化创建并重载工厂方法以创建新产品必须修改父类接口才能支持新的产品

 

 

 

 

 

Cocoa中的抽象工厂模式 - 类族

类簇是基础框架中一种常见的设计模式,是基于抽象工厂的思想,它将若干相关工厂子类集合到一个公有的抽象超类下面。

创建NSNumber实例的方式完全符合抽象工厂模式,如下:

let boolNumber = NSNumber(value: true)
let doubleNumber = NSNumber(value: 2.8)
let intNumber = NSNumber(value: 1)

print("\(object_getClass(boolNumber))")
print("\(object_getClass(doubleNumber))")
print("\(object_getClass(intNumber))")

每个返回对象其实对应着不同的私有子类:

Optional(__NSCFBoolean)
Optional(__NSCFNumber)
Optional(__NSCFNumber)

除了boolNumber是NSCFBoolean,大多数类型都是NSCFNumber,很明显尽管NSNumber对象的类方法返回的是NSNumber实例,但是实际是具体子类的实例,这不就是抽象工厂模式的使用嘛。除了NSNumber,其实NSString、NSArray、NSDictionary都是类簇。

 

参考

iOS 21中设计模式之抽象工厂

 


版权声明:本文为longshihua原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。