抽象工厂模式(Abstract Factory Pattern)
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式何时用
需要创建产品家族和想让制造的相关产品集体起来时使用。
抽象工厂模式好处
- 易于交换“产品系列”,只要更改相应的工厂即可。
抽象工厂模式缺陷
- 建立产品的时候比较繁琐,需要增加和修改较多东西。
抽象工厂模式的代码实现
业务需求
有一个汽车厂商生产两种车辆,根据用户需求提供不同的车型。用户刚好有两种需求对应这两种车型:
- 需求:只买贵的,不买对的
- 需求:经济、安全、实用
- 假设生产一辆汽车需要车身与轮胎两种对象(当然,实际生产中是更多的一系列对象)
设计思路
- 定义车身基类CarBody,土豪车身CarBodyA,普通车身CarBodyB分别继承该基类;
- 定义轮胎基类CarTire,土豪轮胎CarTireA,普通轮胎CarTireB分别继承该基类;
- 定义生产车身与轮胎的原料工厂基类CarIngredientFactory,土豪原料工厂CarIngredientFactoryA,普通原料工厂CarIngredientFactoryB分别继承该基类;
- 定义汽车Car基类,基类中包含车身与轮胎对象,土豪车CarA,普通车CarB分别继承自基类Car;
- 定义组装汽车的工厂基类CarFactory,土豪车组装厂,普通车组装厂分别继承自基类;
- 客户向不同的工厂订车后,工厂就会返回相应原料组成的成品车辆。
代码实现
为了实现上述需求,代码如下:
# -*- coding: utf-8 -*-
class CarBody: # 定义车身基类
def report(self):
pass
class CarBodyA(CarBody): # 定义土豪车身类
def report(self):
return 'Expensive Body'
class CarBodyB(CarBody): # 定义普通车身类
def report(self):
return 'Normal Body'
class CarTire: # 定义车身基类
def report(self):
pass
class CarTireA(CarTire): # 定义土豪车身类
def report(self):
return 'Expensive Tire'
class CarTireB(CarTire): # 定义普通车身类
def report(self):
return 'Normal Tire'
class CarIngredientFactory: # 定义原料抽象工厂类,包含用于生产一系列对象的接口
def create_body(self):
pass
def create_tire(self):
pass
class CarIngredientFactoryA(CarIngredientFactory): # 土豪原料生产类
def create_body(self):
return CarBodyA()
def create_tire(self):
return CarTireA()
class CarIngredientFactoryB(CarIngredientFactory): # 普通原料生产类
def create_body(self):
return CarBodyB()
def create_tire(self):
return CarTireB()
class Car: # 定义汽车基类
carBody = None
carTire = None
def __init__(self, ingredient_factory): # 接收原料工厂,用于获取不同的汽车配件
self.ingredientFactory = ingredient_factory
self.carBody = self.ingredientFactory.create_body() # 生产车身配件
self.carTire = self.ingredientFactory.create_tire() # 生产轮胎配件
def run(self):
print('Speed: ' + str(self.speed))
def description(self):
print('The car are %s & %s.' % (self.carBody.report(), self.carTire.report()))
class CarA(Car): # 土豪车
def __init__(self, ingredient_factory):
Car.__init__(self, ingredient_factory)
self.speed = 200
print('I am rich. I can run faster.')
class CarB(Car): # 普通车
def __init__(self, ingredient_factory):
Car.__init__(self, ingredient_factory)
self.speed = 100
print('I am normal. I can run.')
class CarFactory: # 汽车工厂基类
def get_car(self): # 工厂方法接口
pass
class CarAFactory(CarFactory):
def get_car(self): # 土豪车 实现工厂方法接口
return CarA(CarIngredientFactoryA())
class CarBFactory(CarFactory):
def get_car(self): # 普通车 实现工厂方法接口
return CarB(CarIngredientFactoryB())
if __name__ == '__main__':
factoryA = CarAFactory() # 实例化一个土豪车厂
factoryB = CarBFactory() # 实例化一个普通车厂
a = factoryA.get_car() # 根据车厂类型,获取相应的原料来组装并返回车辆
a.run()
a.description()
b = factoryB.get_car()
b.run()
b.description()
结语
有时工厂方法模式与抽象工厂模式很容易混淆,工厂方法模式是在基类中定义一个工厂的抽象接口,然后派生类负责创建具体对象;抽象工厂模式是维护一个产品家族,由基类定义产品被生产的方法,客户根据基类的接口进行开发。而抽象工厂模式中产品家族的具体某个对象,通常是由工厂方法来实现的。有点绕,需要仔细体会体会。