前言

本文为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()

最终效果:

设计模式-牛刀小试01相关推荐

  1. 【设计模式学习01】设计模式概述,UML图,软件设计原则

    文章目录 1. 设计模式概述 1.1 软件设计模式的产生背景 1.2 软件设计模式的概念 1.3 学习设计模式的必要性 1.4 设计模式分类 2. UML图 2.1 类图概述 2.2 类图的作用 2. ...

  2. 设计模式-牛刀小试02

    前言 本文为datawhale2022年12月组队学习<大话设计模式>最后一次打卡任务,本次完成homework2. [教程地址]https://github.com/datawhalec ...

  3. 设计模式学习01策略模式记录

    (个人记录)策略模式带来的好处就是更加的有弹性,可以很方便的动态改变对象的行为,在已经固定的项目中如果要增加新的类型,在项目中我们要分析变化部分与不变部分. 将变化的部分(也就是策略算法)使用接口的方 ...

  4. 【设计模式作业01】依赖倒转和工厂模式

    在某绘图软件中提供了多种大小不同的画笔(Pen) 在某绘图软件中提供了多种大小不同的画笔(Pen),并且可以给画笔指定不同的颜色,某设计人员针对画笔的结构设计了如图2-11所示的初始类图. 通过仔细分 ...

  5. 【java设计模式】-00目录

    开篇 [java设计模式]-01设计模式简介 创建型模式: [java设计模式]-02工厂模式(Factory Pattern) [java设计模式]-03抽象工厂模式(Abstract Factor ...

  6. 专题:设计模式(精华篇)(Yanlz+单一职责+里氏替换+依赖倒置+接口隔离+迪米特+开放封闭+创建类+结构类+行为类+立钻哥哥)

    <专题:设计模式(精华篇)> 版本 作者 参与者 完成日期 备注 DesignPatterns_Classics_V01_1.0 严立钻 2018.07.31 ##<专题:设计模式( ...

  7. react 布局容器_如何使用容器模式开发React超能力

    react 布局容器 Hello everyone! ? 大家好! ? This time I'm going to tell you about this very useful pattern i ...

  8. 互联网java工程师面试突击第三季知识点总结

    目录 Java集合包 01. HashMap的底层数据结构是什么? 02. JDK1.8中对hash算法和寻址算法是如何优化的? 03.HashMap是如何解决hash碰撞问题的? 04.说说Hash ...

  9. 专题总纲目录 计算机学科基础

    本系列文章主要是计算机学科基础相关知识,偏重基础,也是后面 Linux系统 和 安卓系统 两大领域的基础. 目录 1 计算机基础 2 操作系统 3 设计模式 4 openGL​​​​​​​ 1 计算机 ...

最新文章

  1. unix command
  2. 【python】 读取Excel文件并绘制图表
  3. 让你的网站在移动端健步如飞
  4. 【NLP】从头开始学词向量的预训练
  5. MySQL必知必会——了解SQL/SQL简介/使用MySQL
  6. 停止Java线程,小心interrupt()方法
  7. 在VSCode Remote环境下开发Teams Bot
  8. WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置
  9. java 多线程 举例,Java多线程简单举例
  10. 【Matlab】求解函数导数
  11. Windows下安装 Apache 步骤
  12. tabLayout 设置分割线
  13. 弗吉尼亚理工大学计算机科学,美国弗吉尼亚理工大学计算机科学本科.pdf
  14. vowifi android开关,教你联通VoLTE高清语音一加OnePlus 5T手机设置
  15. 数据库 --- 表的创建(DDL)以及数据的插入、修改和删除(DML)
  16. chorme vue中使用audio自动播放问题
  17. 千牛群发消息怎么发?推荐UiBot千牛群发消息机器人
  18. ev4a ev6 ev8文件转换为mp4翻录教程
  19. NTC热敏电阻电阻与温度之间的转换公式
  20. Ubuntu 出现这个提示“Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend.”?

热门文章

  1. 关于爬虫平台的架构实现和框架的选型(二)--scrapy的内部实现以及实时爬虫的实现...
  2. 项目六 PLC与RobotStudio联合仿真激光切割工作站——系统联调
  3. mysql 服务器安全狗_安装服务器安全狗教程
  4. 聊聊单点登录(SSO)中的CAS认证
  5. ingress-nginx详解和部署方案
  6. SF19 | 基于VWAP(成交量加权平均价格)开发Alpha均线增强策略
  7. Python打包发布
  8. VSD Viewer for Mac,Visio绘图文件阅读器
  9. C# 字节数组、字符串转化
  10. 可以预防耳鸣的两大穴位大家一定要知道