在上一篇文章中介绍了工厂办法形式,其实工厂办法和笼统工厂有许多相似的地方,笼统工厂是工厂办法的升级版,只不过工厂办法形式只出产一个等级的产品,而笼统工厂形式可出产多个等级的产品,能够出产一个产品族的产品。

什么是笼统工厂?

供给一个创立一系列相关或相互依赖目标的接口,而无需指定它们详细的类。

主要人物与关系

  • 笼统工厂(Abstract Factory):供给创立笼统产品的接口,包括多个创立产品的办法。
  • 详细工厂(Concrete Factory):完结了笼统工厂的多个笼统办法,完结详细产品的创立。
  • 笼统产品(Product):描述了产品的标准、功用以及特性等,在笼统工厂形式中有多个笼统产品。
  • 详细产品(Concrete Product):完结了笼统产品的接口,由详细工厂来创立。

UML图

classDiagram
direction BT
class AbstractFactory {
<<笼统工厂>>
+CreateProductA()
+CreateProductB()
}
class ConcreteFactoryA {
<<详细工厂>>
+CreateProductA()
+CreateProductB()
}
class ConcreteFactoryB {
<<详细工厂>>
+CreateProductA()
+CreateProductB()
}
ConcreteFactoryA ..|> AbstractFactory
ConcreteFactoryB ..|> AbstractFactory
class AbstractProductA {
<<笼统产品A>>
}
class AbstractProductB {
<<笼统产品B>>
}
class ConcreteProductA1 {
<<详细产品A1>>
}
class ConcreteProductA2 {
<<详细产品A2>>
}
ConcreteProductA1 ..|> AbstractProductA
ConcreteProductB1 ..|> AbstractProductB
class ConcreteProductB1 {
<<详细产品B1>>
}
class ConcreteProductB2 {
<<详细产品B2>>
}
ConcreteProductA2 ..|> AbstractProductA
ConcreteProductB2 ..|> AbstractProductB
ConcreteFactoryA ..< ConcreteProductA1
ConcreteFactoryA ..< ConcreteProductB1
ConcreteFactoryB ..< ConcreteProductA2
ConcreteFactoryB ..< ConcreteProductB2

举例说明

我们以出产电子产品为例,因为电子产品许多,这儿我们就拿电脑和手机为例,一个工厂出产一种电脑和手机,苹果工厂出产mac和iphone,华为工厂出产华为电脑和华为手机。

  1. 创立笼统产品Phone,以及详细的手机产品:iPhoneHuaweiPhone;创立笼统产品Computer,以及详细的手机产品:MacHuaweiComputer
class Computer {
  func getName() -> String {
    return ""
  }
}
class Mac: Computer {
  override func getName() -> String {
    return "Mac"
  }
}
class HuaweiComputer: Computer {
  override func getName() -> String {
    return "Huawei computer"
  }
}
class Phone {
  func getName() -> String {
    return ""
  }
}
class iPhone: Phone {
  override func getName() -> String {
    return "iPhone"
  }
}
class HuaweiPhone: Phone {
  override func getName() -> String {
    return "Huawei Phone"
  }
}
  1. 创立笼统工厂:ElectronicsAbstractFactory,出产手机和电脑
protocol ElectronicsAbstractFactory {
  func createPhone() -> Phone
  func createComputer() -> Computer
}
  1. 界说详细工厂类AppleElectronicsFactoryHuaweiElectronicsFactory
class AppleElectronicsFactory: ElectronicsAbstractFactory {
  func createPhone() -> Phone {
    return iPhone();
  }
  func createComputer() -> Computer {
    return Mac()
  }
}
class HuaweiElectronicsFactory: ElectronicsAbstractFactory {
  func createPhone() -> Phone {
    return HuaweiPhone();
  }
  func createComputer() -> Computer {
    return HuaweiComputer()
  }
}
  1. 客户端调用
func testClient() {
  let appleFactory = AppleElectronicsFactory()
  let iphone = appleFactory.createPhone()
  let mac = appleFactory.createComputer()
  print("phone: \(iphone.getName()), computer: \(mac.getName())")
  let huaweiFactory = HuaweiElectronicsFactory()
  let huaweiPhone = huaweiFactory.createPhone()
  let huaweiComputer = huaweiFactory.createComputer()
  print("phone: \(huaweiPhone.getName()), computer: \(huaweiComputer.getName())")
}

总结

优点

  1. 易于交流产品系列,由于详细的工厂类,例如let appleFactory = AppleElectronicsFactory(),在一个使用中只需求在初始化的时分呈现一次,故想要改变一个详细的工厂就很简单了。
  2. 让详细的创立实例的进程与客户端别离,客户端是通过笼统接口操纵实例的,产品的详细类也被详细工厂的完结别离,因此详细的产品不会呈现在客户端,减少了代码的耦合。

缺陷

当需求增加一个新的产品时,比如Watch,至少需求增加三个类:Watch笼统类、iWatchHuaweiWatch,一起还需求修正ElectronicsAbstractFactoryAppleElectronicsFactoryHuaweiElectronicsFactory,违背了开闭准则。