python设计模式之抽象工厂模式详解
作者:Spuer_Tiger 发布时间:2023-06-11 22:15:51
抽象工厂模式(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类的继承
来源:https://blog.csdn.net/acceptedday/article/details/117906413


猜你喜欢
- sql 查出一张表中重复的所有记录数据1.表中有id和name 两个字段,查询出name重复的所有数据 select * from xi a
- 爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家?重新理解爬虫中的一些概念爬虫:自动获取网站数据的程序反爬虫:
- 修改数据库字符集:ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [
- 一、super( ) 的用途了解 super() 函数之前,我们首先要知道 super() 的用途是啥?主要用来在子类中调用父类的方法。多用
- easy_install 卸载通过easy_install 安装的模块可以直接通过 easy_install -m Packag
- 本文实例为大家分享了python(列表生成式/器)的具体代码,供大家参考,具体内容如下一、列表生成式#列表生成式是快速生成一个列表的一些公式
- 一、 官网下载安装包: 官网网址:https://www.python.org/ 我下载的是3.6.3版本,如下图:&n
- 目录1、简单循环 Simple loops2、简单循环但是使用了线程Simple loops but threaded3、定时调度库 Sch
- 一.图像金字塔原理上一篇文章讲解的图像采样处理可以降低图像的大小,本文将补充图像金字塔知识,了解专门用于图像向上采样和向下采样的pyrUp(
- while语句打印1-20的整数,并且每行打印五个数,为了实现每行5个数,我们使用一个if判断语句来实现,判断当打印出5个数之后,自动换行打
- 在编写JavaScript代码的时候存在的一些方法和技巧,虽然有时候条条大路都通向罗马,但是也许总会有那么一条最短的路径可走。本文将一些都知
- 实例如下:<?php /** * @name thumb 缩略图函数 * @param sting  
- PyCaret 是一个开源、低代码的 Python 机器学习库,可自动执行机器学习工作流。它是一种端到端的机器学习和模型管理工具,可以以指数
- 本文简介前段时间,黄同学写了一篇《MySQL窗口实战》文章(文章如下),但是里面大多数是以实战练习为主,没有做详细的解释。传送门:MySQL
- 先由exp把数据卸出到文件系统, 产生一个.dmp文件, 然后必要时再由imp将数据装入数据库. 对于一般中小型数据库来说, 全数据库的ex
- 使用程序难免会有出错的时候,如何从大篇代码中找出错误,不仅考验能力,还要考验小伙们的耐心。辛辛苦苦敲出的代码运行不出结果,非常着急是可以理解
- openpyxl是一个读写Excel文档的Python库,能够同时读取和修改Excel文档。openpyxl是一个开源项目,因此在使用之前需
- 本文实例讲述了python提取页面内url列表的方法。分享给大家供大家参考。具体实现方法如下:from bs4 import Beautif
- 研究了一段时间酷狗音乐的接口,完美破解了其vip音乐下载方式,想着能更好的追求开源,故写下此篇文章,本文仅供学习参考。虽然没什么
- 本文实例讲述了html静态页面调用php文件的方法。分享给大家供大家参考。具体方法如下:静态页面中看上去好像是不能直接调用php文件的,但是