抽象工厂模式(Abstract Factory Pattern):属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象。
意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决: 主要解决接口选择的问题。
何时使用: 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决: 在一个产品族里面,定义多个产品。
关键代码: 在一个工厂里聚合多个同类产品。
优点: 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。抽象工厂模式相较于工厂模式,划分更加明确清晰,面对复杂的生产任务,管理和生产性能会更加高效。
缺点: 产品族扩展非常困难,要增加一整个系列的某一产品。
注意事项: 产品族难扩展,产品等级易扩展。
应用实例: 对于一个生产水果的工厂,工厂模式主要针对一种水果创建一个涵盖与该水果相关所有业务的工厂(例如:葡萄的运输、保存、加工、包装、售卖等相关业务全部被该工厂承包);而抽象工厂模式主要针对生产其中的某一环节进行创建相应的工厂(例如:运输工厂负责管理所有水果的运输,售卖工厂负责管理所有水果的价格和售卖,库存工厂负责管理所有水果的库存计数等)
。
那我们来一起使用抽象工厂模式,构建一个购买水果的收银小项目吧!(づ。◕ᴗᴗ◕。)づ
实现的思路:
- 项目的主体包含6个部分:消费者(买水果的人),水果工厂(卖水果的人),水果工厂旗下的子工厂(品种工厂、价格工厂、包装工厂、称重工厂
- 消费者主要向水果工厂传达“购买需求”的相关信息(水果的种类、包装、重量等…);
水果工厂主要针对消费者的不同“购买需求”将任务分派给子工厂进行执行;
品种工厂负责管理水果的种类,价格工厂负责管理水果的价格,称重工厂负责水果的称重,包装工厂负责水果的包装方式。
项目的UML用例图如下:
实现的代码如下:
class FruitClass:
# 品种工厂
def get_name(self, name_index):
if name_index == 0:
name_object = OrangeClass()
elif name_index == 1:
name_object = Hami_MelonClass()
elif name_index == 2:
name_object = GrapeClass()
else:
name_object = None
return name_object
class OrangeClass:
# 橘子类
def __init__(self):
self.name = "橘子"
def print_name(self):
print("您购买的水果为:%s" % self.name)
class Hami_MelonClass:
# 哈密瓜类
def __init__(self):
self.name = "哈密瓜"
def print_name(self):
print("您购买的水果为:%s" % self.name)
class GrapeClass:
# 葡萄类
def __init__(self):
self.name = "葡萄"
def print_name(self):
print("您购买的水果为:%s" % self.name)
class FruitWeight:
# 称重工厂
def __init__(self, weight):
self.weight = float(weight)
def print_weight(self):
print("该水果的重量为:%.2f千克" % self.weight)
class FruitPrice:
# 价格工厂
def get_price(self, name_index, variety):
if name_index == 0:
price_object = OrangePrice(variety)
elif name_index == 1:
price_object = Hami_MelonPrice()
elif name_index == 2:
price_object = GrapePrice()
else:
price_object = None
return price_object
class OrangePrice:
# 橘子价格类
def __init__(self, variety):
self.variety = variety
if self.variety == 1:
self.price = 8.5
else:
self.price = 11.0
def print_price(self):
print("该水果的单价为:%.2f元/千克" % self.price)
class Hami_MelonPrice:
# 哈密瓜价格类
def __init__(self):
self.price = 24.3
def print_price(self):
print("该水果的价格为:%.2f元/千克" % self.price)
class GrapePrice:
# 葡萄价格类
def __init__(self):
self.price = 16.2
def print_price(self):
print("该水果的价格为:%.2f元/千克" % self.price)
return self.price
class FruitPack:
# 包装工厂
def __init__(self, pack):
if pack == 1:
self.pack = "散称"
else:
self.pack = "盒装"
def print_pack(self):
print("该水果的打包方式为:%s" % self.pack)
class FruitFactory:
def __init__(self, name_index, weight, variety, pack):
# 任务的分配,品种、重量、价格、包装方式
self.name_object = FruitClass().get_name(name_index)
self.weight_object = FruitWeight(weight)
self.price_object = FruitPrice().get_price(name_index, variety)
self.pack_object = FruitPack(pack)
def print_purchase(self):
# 计算购买的金额
money = self.price_object.price * self.weight_object.weight
print("需要支付的金额共计为:%.2f元" % money)
def show_info(self):
# 展示最终的购买信息
self.name_object.print_name()
self.weight_object.print_weight()
self.price_object.print_price()
self.pack_object.print_pack()
self.print_purchase()
print("-*-" * 20)
class Consumer:
# 消费者类
def __init__(self):
print("-*-" * 20)
# 输入原始的“购买需求”信息
self.name = input("请输入你要购买的水果名称:0.橘子 1.哈密瓜 2.葡萄\n")
self.weight = input("请输入你要购买水果的重量(kg):\n")
self.variety = input("如果您购买橘子,我们有2种橘子:0.不买橘子 1.甘橘 2.砂糖橘\n")
self.pack = input("请您选择该水果的包装方式:1.散称 2.盒装\n")
print("-*-" * 20)
def request(self):
# 返回相关的购买信息
return self.name, self.weight, self.variety, self.pack
if __name__ == '__main__':
# 创建顾客
buyer = Consumer()
# 拿到顾客的购买信息
buy_info = buyer.request()
# 使用水果工厂,传达指令至旗下的子工厂并执行购买操作
buy_res = FruitFactory(int(buy_info[0]), int(buy_info[1]), int(buy_info[2]), int(buy_info[3]))
# 购买信息的展示
buy_res.show_info()
相关的测试用例:
本文关于设计模式的讲解思想,参考链接:抽象工厂模式
如果有对python类的创建和继承等用法还不熟悉的小伙伴,请参考这篇博客: python类的继承
往期推荐: 点这里->Python:水果与设计模式-工厂模式