设计模式-牛刀小试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
输出功能。
二、任务分析
根据要求,应该采用工厂方法模式以及策略模式。具体工作如下:
- 首先创建抽象的费用类
CashSuper
和产品工厂类ProductFactory
,用来分别代表不同收费策略类公共接口和具体产品的公共接口; - 分别创建收费策略类
CashNormal
、CashRebate
和CashReturn
,继承CashSuper
,用来实现相应的收费策略; - 再分别创建具体产品类
NormalProductFactory
、RebateProductFactory
和ReturnProductFactory
,继承于抽象类ProductFactory
,在三个类中各自定义创建对应具体产品实例的方法; - 创建策略模式上下文类
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()
最终效果:
设计模式-牛刀小试01相关推荐
- 【设计模式学习01】设计模式概述,UML图,软件设计原则
文章目录 1. 设计模式概述 1.1 软件设计模式的产生背景 1.2 软件设计模式的概念 1.3 学习设计模式的必要性 1.4 设计模式分类 2. UML图 2.1 类图概述 2.2 类图的作用 2. ...
- 设计模式-牛刀小试02
前言 本文为datawhale2022年12月组队学习<大话设计模式>最后一次打卡任务,本次完成homework2. [教程地址]https://github.com/datawhalec ...
- 设计模式学习01策略模式记录
(个人记录)策略模式带来的好处就是更加的有弹性,可以很方便的动态改变对象的行为,在已经固定的项目中如果要增加新的类型,在项目中我们要分析变化部分与不变部分. 将变化的部分(也就是策略算法)使用接口的方 ...
- 【设计模式作业01】依赖倒转和工厂模式
在某绘图软件中提供了多种大小不同的画笔(Pen) 在某绘图软件中提供了多种大小不同的画笔(Pen),并且可以给画笔指定不同的颜色,某设计人员针对画笔的结构设计了如图2-11所示的初始类图. 通过仔细分 ...
- 【java设计模式】-00目录
开篇 [java设计模式]-01设计模式简介 创建型模式: [java设计模式]-02工厂模式(Factory Pattern) [java设计模式]-03抽象工厂模式(Abstract Factor ...
- 专题:设计模式(精华篇)(Yanlz+单一职责+里氏替换+依赖倒置+接口隔离+迪米特+开放封闭+创建类+结构类+行为类+立钻哥哥)
<专题:设计模式(精华篇)> 版本 作者 参与者 完成日期 备注 DesignPatterns_Classics_V01_1.0 严立钻 2018.07.31 ##<专题:设计模式( ...
- react 布局容器_如何使用容器模式开发React超能力
react 布局容器 Hello everyone! ? 大家好! ? This time I'm going to tell you about this very useful pattern i ...
- 互联网java工程师面试突击第三季知识点总结
目录 Java集合包 01. HashMap的底层数据结构是什么? 02. JDK1.8中对hash算法和寻址算法是如何优化的? 03.HashMap是如何解决hash碰撞问题的? 04.说说Hash ...
- 专题总纲目录 计算机学科基础
本系列文章主要是计算机学科基础相关知识,偏重基础,也是后面 Linux系统 和 安卓系统 两大领域的基础. 目录 1 计算机基础 2 操作系统 3 设计模式 4 openGL 1 计算机 ...
最新文章
- unix command
- 【python】 读取Excel文件并绘制图表
- 让你的网站在移动端健步如飞
- 【NLP】从头开始学词向量的预训练
- MySQL必知必会——了解SQL/SQL简介/使用MySQL
- 停止Java线程,小心interrupt()方法
- 在VSCode Remote环境下开发Teams Bot
- WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置
- java 多线程 举例,Java多线程简单举例
- 【Matlab】求解函数导数
- Windows下安装 Apache 步骤
- tabLayout 设置分割线
- 弗吉尼亚理工大学计算机科学,美国弗吉尼亚理工大学计算机科学本科.pdf
- vowifi android开关,教你联通VoLTE高清语音一加OnePlus 5T手机设置
- 数据库 --- 表的创建(DDL)以及数据的插入、修改和删除(DML)
- chorme vue中使用audio自动播放问题
- 千牛群发消息怎么发?推荐UiBot千牛群发消息机器人
- ev4a ev6 ev8文件转换为mp4翻录教程
- NTC热敏电阻电阻与温度之间的转换公式
- Ubuntu 出现这个提示“Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend.”?
热门文章
- 关于爬虫平台的架构实现和框架的选型(二)--scrapy的内部实现以及实时爬虫的实现...
- 项目六 PLC与RobotStudio联合仿真激光切割工作站——系统联调
- mysql 服务器安全狗_安装服务器安全狗教程
- 聊聊单点登录(SSO)中的CAS认证
- ingress-nginx详解和部署方案
- SF19 | 基于VWAP(成交量加权平均价格)开发Alpha均线增强策略
- Python打包发布
- VSD Viewer for Mac,Visio绘图文件阅读器
- C# 字节数组、字符串转化
- 可以预防耳鸣的两大穴位大家一定要知道