Python:水果与设计模式-工厂模式

工厂模式(Factory Pattern):属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们 在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

意图 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决 主要解决接口选择的问题。

何时使用 我们明确地计划不同条件下创建不同实例时。

如何解决 让其子类实现工厂接口。

关键代码 创建过程在其子类执行。

优点 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

注意事项 作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

应用实例我想买一些水果(橘子、哈密瓜和葡萄),我可以直接从水果工厂里面购买,但是我不需要知道这些水果的产地是哪里的,它们是如何运输和包装的,以及水果工厂的相关流水线是如何运作的。

在这里插入图片描述


那我们来一起看看如何使用工厂模式,实现一个购买不同水果的小项目?(づ。◕ᴗᴗ◕。)づ

实现的思路

  • 项目的主体包含3个部分:消费者(买水果的人),水果工厂(卖水果的人),水果大类(实现隐藏的工厂内部细节)
  • 消费者主要向水果工厂传达“购买需求”的相关信息(水果的种类、包装、重量等...);
  • 水果工厂主要针对消费者的不同“购买需求”将调用不同的水果大类中的子类方法;
  • 水果大类主要划分为各种小类,针对每一类水果有独特的设计实现细节。

项目的UML用例图如下:

在这里插入图片描述


实现的代码如下:

class Fruit:
    # 水果大类
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
        self.price = None
	
    # 计算购买金额的抽象接口
    def purchase(self):
        pass
	# 展示购买信息的抽象接口
    def show(self):
        pass


class Orange(Fruit):
    # 橘子类
    def __init__(self, name, weight, variety):
        Fruit.__init__(self, name, weight)
        # 不同的橘子类型,价格不同
        if variety == 1:
            self.price = 8.5
        else:
            self.price = 11.0
        # 设定购买的橘子的类型
        self.variety = variety

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class Hami_Melon(Fruit):
    # 哈密瓜类
    def __init__(self, name, weight):
        Fruit.__init__(self, name, weight)
        # 设定哈密瓜的单价
        self.price = 24.3

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class Grape(Fruit):
    # 葡萄类
    def __init__(self, name, weight, pack):
        Fruit.__init__(self, name, weight)
        # 设定葡萄的单价
        self.price = 16.2
        # 设定葡萄的包装方式
        self.pack = pack

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class FruitFactory:
    # 水果工厂类
    def get_info(self, name, weight, variety, pack):
        weight = float(weight)
        variety, pack = int(variety), int(pack)
        if variety == 0 and pack == 0:
            new_object = Hami_Melon(name, weight)
            return new_object
        elif variety > 0 and pack == 0:
            new_object = Orange(name, weight, variety)
            return new_object
        elif variety == 0 and pack > 0:
            new_object = Orange(name, weight, pack)
            return new_object
        else:
            return None


class Consumer:
    # 消费者类
    def __init__(self):
        # 输入原始的“购买需求”信息
        self.name = input("请输入你要购买的水果名称:orange / hami_Melon / grape\n")
        self.weight = input("请输入你要购买水果的重量(kg):\n")
        self.variety = input("如果您购买橘子,我们有2种橘子:0.不买橘子 1.甘橘 2.砂糖橘\n")
        self.pack = input("如果您购买葡萄,有2中包装方式:0.不买葡萄 1.散称 2.盒装\n")

    def request(self):
        # 返回相关的购买信息
        return self.name, self.weight, self.variety, self.pack


if __name__ == '__main__':
    # 创建顾客
    buyer = Consumer()
    # 拿到顾客的购买信息
    buy_info = buyer.request()
    # 使用水果工厂,传达指令至水果大类并执行购买操作
    buy_res = FruitFactory().get_info(buy_info[0], buy_info[1], buy_info[2], buy_info[3])
    # 购买信息的展示
    buy_res.show()

相关的测试用例:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文关于设计模式的讲解思想,参考链接:抽象工厂模式
如果有对python类的创建和继承等用法还不熟悉的小伙伴,请参考这篇博客: python类的继承

评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super__Tiger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值