设计模式-牛刀小试01

前言

本文为datawhale2022年12月组队学习《大话设计模式》task4打卡学习,本次完成homework1。
【教程地址】https://github.com/datawhalechina/sweetalk-design-pattern

一、任务描述

1.1 背景

小李已经是一个工作一年的初级工程师了,他所在的公司是一家大型购物商场。随着各种网络购物软件兴起,老板也想做一个商场的购物 APP。分给小李的是一个一个订单结算模块,需要支持各种不同的结算策略。

1.2 需求

请帮小李写一个订单结算模块,要求支持多种结算策略:

  • 原价
  • 打 X 折
  • 满减,满 X 元减 Y 元

请注意,商品有多种类型,每种类型可能会参与不同的活动,自然需要支持不同的结算策略。

1.3 任务

共三个小任务:

  • Q1:方案设计。
  • Q2:代码实现及结果截图。
  • Q3:解释为什么要用这些模式。

1.4 要求

要求如下:

  • 输入是一揽子商品,输出是最后的订单金额。
  • 至少包含两种商品,每种使用不同的结算策略,策略可任选其中一个或两个组合(比如满减 + 打折)。
  • 不要实现具体函数或方法的逻辑,可以使用 print 输出功能。

二、任务分析

根据要求,应该采用工厂方法模式以及策略模式。具体工作如下:

  1. 首先创建抽象的费用类CashSuper和产品工厂类ProductFactory,用来分别代表不同收费策略类公共接口和具体产品的公共接口;
  2. 分别创建收费策略类CashNormalCashRebateCashReturn,继承CashSuper,用来实现相应的收费策略;
  3. 再分别创建具体产品类NormalProductFactoryRebateProductFactoryReturnProductFactory,继承于抽象类ProductFactory,在三个类中各自定义创建对应具体产品实例的方法;
  4. 创建策略模式上下文类CashContext,前端界面通过选择不同的销售策略,从而创建不同具体产品类的实例。

三、代码实现

整体上参考了策略模式案例的代码,自己在上面有所修改:

# -*- coding:utf-8 -*-
'''
@File    :   StrategyCash.py
@Time    :   2022/12/21 10:58:24
@Author  :   ziyuan
@Version :   1.0
@Contact :   1104009634@qq.com
@Desc    :   任务01订单结算模块策略模式实现
'''

# here put the import lib
import tkinter
import tkinter.ttk


# 收费的接口类
class CashSuper(object):
    def __init__(self):
        pass
    def accept_cash(self,money):
        pass

# 正常收费
class CashNormal(CashSuper):
    def accept_cash(self,money):
        return money

# 打折收费
class CashRebate(CashSuper):
    __moneyRebate = 1
    def cash_rebate(self,moneyRebateStr):
        self.__moneyRebate = float(moneyRebateStr)
    def accept_cash(self,money):
        return money*self.__moneyRebate

# 返利收费
class CashReturn(CashSuper):
    __moneyCondition = 0
    __moneyReturn = 0
    def cash_return(self,moneyConditionStr,moneyReturnStr):
        self.__moneyCondition = float(moneyConditionStr)
        self.__moneyReturn = float(moneyReturnStr)
    def accept_cash(self,money):
        result = money
        if (money >= self.__moneyCondition):
            result = money - money // self.__moneyCondition * self.__moneyReturn
        return result


# 产品的抽象类
class ProductFactory(object):
    def __init__(self,name,price):
        self.__product_name = name
        self.__product_price = price
    def set_product_name(self,name):
        self.__product_name = name
    def get_product_name(self):
        return self.__product_name
    def set_product_price(self,price):
        self.__product_price = price
    def get_product_price(self):
        return self.__product_price
    def get_cash(self):
        pass

class NormalProductFactory(ProductFactory):
    def __init__(self,name,price):
        super().__init__(name,price)
        self.cs = CashNormal()

    def get_cash(self):
        return self.cs.accept_cash(self.get_product_price())

class RebateProductFactory(ProductFactory):
    def __init__(self,name,price):
        super().__init__(name,price)
        self.cs = CashRebate()
        self.cs.cash_rebate("0.8")

    def get_cash(self):
        return self.cs.accept_cash(self.get_product_price())

class ReturnProductFactory(ProductFactory):
    def __init__(self,name,price):
        super().__init__(name,price)
        self.cs = CashReturn()
        self.cs.cash_return("300","100")

    def get_cash(self):
        return self.cs.accept_cash(self.get_product_price())


# 策略模式上下文类实现
class CashContext(object):
    def __init__(self,typ,name,price):
        if typ == "正常收费":
            self.product = NormalProductFactory(name,price)
        elif typ == "打8折":
            self.product = RebateProductFactory(name,price)
        elif typ == "满300返100":
            self.product = ReturnProductFactory(name,price)
        
    def get_result(self):
        return self.product.get_cash()

# 前端
class CashWindow(object):
    def __init__(self):
        self.total = 0
        root = tkinter.Tk()
        self.label1 = tkinter.Label(root,text="商品名称:")
        self.txtName = tkinter.Entry(root,width = 24,)
        self.label2 = tkinter.Label(root,text="商品价格:")
        self.txtPrice = tkinter.Entry(root,width = 24,)
        self.ibxList = tkinter.Text(root,width = 45, height = 10)
        self.label4 = tkinter.Label(root,text="总计:")
        
        self.iblResult = tkinter.StringVar()
        self.iblResult.set("%.2f"%self.total)
        self.result = tkinter.Label(root,textvariable=self.iblResult, height = 2, font = ('TimeNewsRoman',24))
        self.button = tkinter.Button(root,text="确定",width = 10,command = self.btnOk_click)
        self.buttonReset = tkinter.Button(root,text="重置",width = 10,command = self.btnReset_click)

        self.label3 = tkinter.Label(root,text="计算方式:")
        self.comboVar = tkinter.StringVar()
        self.combobox = tkinter.ttk.Combobox(root, textvariable = self.comboVar,width = 22,)
        self.combobox['value'] = ("正常收费","打8折","满300返100")
        self.combobox.current(0)
        self.layout()
        root.mainloop()
       
    def refresh(self):
        self.txtName.delete('0','end')
        self.txtPrice.delete('0','end')

    def layout(self):
        self.label1.grid(row = 0, column = 0, padx = (10,0), pady = 10)
        self.txtName.grid(row = 0, column = 1, pady = 10,padx = (0,5),)
        self.label2.grid(row = 1, column = 0, padx = (10,0))
        self.txtPrice.grid(row = 1, column = 1,padx = (0,5),)
        self.label3.grid(row = 2, column = 0, padx = (10,0))
        self.combobox.grid(row = 2, column = 1,padx = (0,5),pady = 10)

        self.ibxList.grid(row = 4, column = 0,columnspan = 4,padx = (5,5),pady = 10)
        self.label4.grid(row = 5, column = 0, padx = (10,0))
        self.result.grid(row = 5, column = 1,columnspan = 3, rowspan = 2)
        self.button.grid(row = 0, column = 2, columnspan = 2,pady = 10,  padx = (0,10))
        self.buttonReset.grid(row = 1, column = 2, columnspan = 2, padx = (0,10))

    def btnReset_click(self):
        self.total = 0
        self.ibxList.delete('1.0','end')
        self.iblResult.set("%.2f"%self.total)
        self.refresh()

    # 主要部分
    def btnOk_click(self):
        csuper = CashContext(self.comboVar.get(),self.txtName.get(),float(self.txtPrice.get()))
        totalPrice = float(csuper.get_result())
        self.total = self.total + totalPrice
        self.ibxList.insert('end',"商品名称:"+self.txtName.get()+
                                ",商品价格:" +self.txtPrice.get()+
                                ",销售策略:"+self.comboVar.get()+
                                "。合计:%.2f"%(totalPrice)+"\n")
        self.iblResult.set("%.2f"%self.total)
        self.refresh()

if __name__ == '__main__':
    CashWindow()

最终效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值