设计模式-牛刀小试01

news/2024/11/19 19:34:33/

前言

本文为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):passdef accept_cash(self,money):pass# 正常收费
class CashNormal(CashSuper):def accept_cash(self,money):return money# 打折收费
class CashRebate(CashSuper):__moneyRebate = 1def cash_rebate(self,moneyRebateStr):self.__moneyRebate = float(moneyRebateStr)def accept_cash(self,money):return money*self.__moneyRebate# 返利收费
class CashReturn(CashSuper):__moneyCondition = 0__moneyReturn = 0def cash_return(self,moneyConditionStr,moneyReturnStr):self.__moneyCondition = float(moneyConditionStr)self.__moneyReturn = float(moneyReturnStr)def accept_cash(self,money):result = moneyif (money >= self.__moneyCondition):result = money - money // self.__moneyCondition * self.__moneyReturnreturn result# 产品的抽象类
class ProductFactory(object):def __init__(self,name,price):self.__product_name = nameself.__product_price = pricedef set_product_name(self,name):self.__product_name = namedef get_product_name(self):return self.__product_namedef set_product_price(self,price):self.__product_price = pricedef get_product_price(self):return self.__product_pricedef get_cash(self):passclass 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 = 0root = 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 = 0self.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 + totalPriceself.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()

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


http://www.ppmy.cn/news/5546.html

相关文章

【Python机器学习】条件随机场模型CRF及在中文分词中实战(附源码和数据集)

需要源码请点赞关注收藏后评论区留言私信~~~ 基本思想 假如有另一个标注序列(代词 动词 名词 动词 动词),如何来评价哪个序列更合理呢? 条件随机场的做法是给两个序列“打分”,得分高的序列被认为是更合理的。既然要…

新冠确诊阳性后的第一篇博客,一文带你学习SQL注入

新冠确诊阳性后的第一篇博客,一文带你学习SQL注入1.你好SQL注入2.盲注3.Timing Attack4.常见的攻击技巧5.SQL CoIumn Truncation6.防御SQL注入SQL注入防御的误区使用预编译语句使用存储过程SQL注入攻击属于注入攻击的一种,注入攻击的本质,是把…

【Linux 内核 内存管理】物理内存组织结构

一、 UMA和NUMA两种模型 共享存储型多处理机有两种模型 一致内存访问(Uniform-Memory-Access,简称UMA)模型 非一致内存访问(Nonuniform-Memory-Access,简称NUMA)模型 UMA模型 物理存储器被所有处理器件均…

揭秘百度智能测试在测试定位领域实践

作者 | intelligents 前几篇,分别介绍了测试活动测试输入、测试执行、测试分析、测试定位和测试评估五个步骤中测试输入、执行、分析、评估的智能化研究和实践,本章节重点介绍测试定位环节的智能化实践。 测试定位的主要作用是在构建失败或问题发生后&…

LabVIEW在两台计算机之间传输数据

LabVIEW在两台计算机之间传输数据 有几种网络协议可用于完成此任务。使用正确的网络协议白皮书将完成为应用选择正确协议的任务。它涵盖了控制和监视应用中最常用的通信模型,并根据配置、性能、易用性等推荐最适合每种情况的网络协议。 参考的白皮书重点介绍了三种…

LLVM中矩阵Matrix的实现分析

1 背景说明 Clang提供了C/C语言对矩阵的扩展支持,以方便用户使用可变大小的二维数据类型来实现计算,目前该特性还是实验版,设计和实现都在变化中。LLVM目前设计为支持小型列矩阵(column major),其对矩阵的…

Python中的基本数据类型

文章目录前言一、字符串类型字符串表示方法二、数字类型1. 整数2.浮点数3.复数三、布尔类型总结前言 我们一般在电脑中存储的数据有多种数据类型。比如下图这张员工工资表: 表中员工姓名可以用字符串类型存储(比如"李世民"、“侯君集”&#…

【经典问题:HanoiTower(汉诺塔)】

🎁HanoiTower🎅HanoiTower问题描述🎅🎅模拟推导🎅🎅🎅问题的两种形式🎄求解移动总次数🎄🎄打印详细的移动过程🎅HanoiTower问题描述 汉诺塔问题&a…