python设计模式之抽象工厂模式详解

 更新时间:2021年07月06日 09:11:32   作者:Spuer_Tiger  
这篇文章主要介绍了python设计模式之抽象工厂模式,通过案例分析,主要说明了该项设计模式的主要解决问题,优缺点以及何时使用等,以下就是详细内容,需要的朋友可以参考下

抽象工厂模式(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设计模式之抽象工厂模式的文章就介绍到这了,更多相关python抽象工厂模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现随机生成迷宫并自动寻路

    Python实现随机生成迷宫并自动寻路

    最近在学习Python,正好今天在学习随机数,本文实现了Python实现随机生成迷宫并自动寻路,感兴趣的可以了解一下
    2021-06-06
  • Python中byte字符串转string的实现

    Python中byte字符串转string的实现

    本文主要介绍了Python中byte字符串转string的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 基于Python利用Faker批量测试数据

    基于Python利用Faker批量测试数据

    这篇文章主要介绍了基于Python利用Faker批量测试数据。测试过程中,经常需要批量去造数据,方法有很多,最简单方便的应该是使用python 的一个三方库Faker。下面我们就来看看三方库Faker如何批量测试数据,需要的朋友可以参考一下
    2022-03-03
  • Python之lambda匿名函数及map和filter的用法

    Python之lambda匿名函数及map和filter的用法

    今天小编就为大家分享一篇关于Python之lambda匿名函数及map和filter的用法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Python random库使用方法及异常处理方案

    Python random库使用方法及异常处理方案

    这篇文章主要介绍了python random库使用方法及异常处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 十个Python经典小游戏的代码合集

    十个Python经典小游戏的代码合集

    这篇文章主要为大家分享十个Python经典的小游戏代码,非常适合Python初学者练手。文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-05-05
  • 一篇文章搞懂python的转义字符及用法

    一篇文章搞懂python的转义字符及用法

    这篇文章主要介绍了一篇文章搞懂python的转义字符及用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Python结合spaCy 进行简易自然语言处理

    Python结合spaCy 进行简易自然语言处理

    这篇文章主要为大家介绍了Python结合spaCy进行简易自然语言处理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Python使用gensim计算文档相似性

    Python使用gensim计算文档相似性

    在文本处理中,比如商品评论挖掘,有时需要了解每个评论分别和商品的描述之间的相似度,以此衡量评论的客观性。那么python 里面有计算文本相似度的程序包吗,恭喜你,不仅有,而且很好很强大。下面我们就来体验下gensim的强大
    2016-04-04
  • python绘制直线的方法

    python绘制直线的方法

    这篇文章主要为大家详细介绍了python绘制直线的方法,绘制直线通用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06

最新评论