在上一篇文章中介绍了工厂方法模式,其实工厂方法和抽象工厂有很多相似的地方,抽象工厂是工厂方法的升级版,只不过工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品,可以生产一个产品族的产品。
什么是抽象工厂?
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要角色与关系
- 抽象工厂(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,华为工厂生产华为电脑和华为手机。
- 创建抽象产品
Phone
,以及具体的手机产品:iPhone
和HuaweiPhone
;创建抽象产品Computer
,以及具体的手机产品:Mac
和HuaweiComputer
swift
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"
}
}
- 创建抽象工厂:
ElectronicsAbstractFactory
,生产手机和电脑
swift
protocol ElectronicsAbstractFactory {
func createPhone() -> Phone
func createComputer() -> Computer
}
- 定义具体工厂类
AppleElectronicsFactory
和HuaweiElectronicsFactory
swift
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()
}
}
- 客户端调用
swift
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())")
}
总结
优点
- 易于交换产品系列,由于具体的工厂类,例如
let appleFactory = AppleElectronicsFactory()
,在一个应用中只需要在初始化的时候出现一次,故想要改变一个具体的工厂就很容易了。 - 让具体的创建实例的过程与客户端分离,客户端是通过抽象接口操纵实例的,产品的具体类也被具体工厂的实现分离,因此具体的产品不会出现在客户端,减少了代码的耦合。
缺点
当需要添加一个新的产品时,比如Watch
,至少需要增加三个类:Watch
抽象类、iWatch
、HuaweiWatch
,同时还需要修改ElectronicsAbstractFactory
、AppleElectronicsFactory
、HuaweiElectronicsFactory
,违背了开闭原则。