前言
本文为datawhale2022年12月组队学习《大话设计模式》最后一次打卡任务,本次完成homework2。
【教程地址】https://github.com/datawhalechina/sweetalk-design-pattern
一、任务描述
1.1 背景
小李已经是一个工作一年的初级工程师了,他所在的公司是一家大型购物商场。随着各种网络购物软件兴起,老板也想做一个商场的购物 APP。分给小李的是一个一个订单结算模块,需要支持各种不同的结算策略。
1.2 需求
帮小李写一个订单结算模块,要求支持 原价、打 X 折 、满减,满 X 元减 Y 元 三种结算策略。
请增加商品状态,至少包括在售、缺货、上架中三种状态。
另外,一种商品在上架前需要经过库存中心、销售中心、经理审核,请增加商品上架审核功能。
1.3 任务
共三个小任务:
- Q1:方案设计。
- Q2:代码实现及结果截图。
- Q3:解释为什么要用这些模式。
1.4 要求
要求如下:
- 输入是一揽子商品,输出是最后的订单金额,请检查订单中商品的状态,只结算在售状态商品。
- 至少包含两种商品,每种使用不同的结算策略,策略可任选其中一个或两个组合(比如满减 + 打折)。
- 对于商品上架审核功能,输入要补货(缺货状态)的商品和数量,输出不同审核状态,审核结束前,商品处于「上架中」。
- 不要实现具体函数或方法的逻辑,可以使用
print
输出功能。
二、任务分析
首先拆解一下问题,这个系统需要实现商品结算和商品上架审核两个大的功能模块。
2.1 商品结算
这部分可以采用工厂方法模式以及策略模式。代码如下
# -*- coding:utf-8 -*-
# 收费的抽象接口类
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,number,price,stage):
self.__product_name = name
self.__product_number = number
self.__product_price = price
self.__product_stage = stage
# OnSale:在售; OutOfStock:缺货; InProcess:上架中。
def set_product_name(self,name):
self.__product_name = name
def get_product_name(self):
return self.__product_name
def set_product_number(self,number):
self.__product_number = number
def get_product_number(self):
return self.__product_number
def set_product_price(self,price):
self.__product_price = price
def get_product_price(self):
return self.__product_price
def set_product_stage(self,stage):
self.__product_stage = stage
def get_product_stage(self):
return self.__product_stage
def get_cash(self):
pass
class NormalProductFactory(ProductFactory):
def __init__(self,name,number,price,stage):
super().__init__(name,number,price,stage)
self.cs = CashNormal()
def get_cash(self):
return self.cs.accept_cash(self.get_product_price())
class RebateProductFactory(ProductFactory):
def __init__(self,name,number,price,stage):
super().__init__(name,number,price,stage)
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,number,price,stage):
super().__init__(name,number,price,stage)
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,name,number,price,stage,typ):
if typ == "正常收费":
self.product = NormalProductFactory(name,number,price,stage)
elif typ == "打8折":
self.product = RebateProductFactory(name,number,price,stage)
elif typ == "满300返100":
self.product = ReturnProductFactory(name,number,price,stage)
def get_type(self):
return self
def get_result(self):
return self.product.get_cash()
采用这种方式的商品,其产品的初始化需要采用:
product = CashContext("核桃",200,2,"上架中","满300返100")
这种方式。
2.2 商品上架审核
这部分非常明显,需要采用职责链模式:
# -*- coding:utf-8 -*-
class Request(object):
__product = None
def get_product(self):
return self.__product
def set_product(self,product):
self.__product = product
product = property(get_product,set_product)
# 商品审核
class ProductVerify(object):
__organ = None # 审核组织
__stage_tag = None
__superior = None
def set_organ(self,organ):
self.__organ = organ
def get_organ(self):
return self.__organ
def set_stage_tag(self,stage_tag):
self.__stage_tag = stage_tag
def get_stage_tag(self):
return self.__stage_tag
def set_superior(self,superior):
self.__superior = superior
def get_superior(self):
return self.__superior
def request_applications(self,request:Request):
pass
organ = property(get_organ,set_organ)
stage_tag = property(get_stage_tag,set_stage_tag)
superior = property(get_superior,set_superior)
# 库存中心
class StockCenter(ProductVerify):
def __init__(self):
self.organ = "库存中心"
def request_applications(self,request:Request):
print(f"{request.product}上架经过了{self.organ}批准!")
self.stage_tag = "上架中"
print(f"{request.product}此时处于{self.stage_tag}的状态")
self.superior.request_applications(request)
# 销售中心
class SalesCenter(ProductVerify):
def __init__(self):
self.organ="销售中心"
def request_applications(self,request:Request):
print(f"{request.product}上架经过了{self.organ}批准!")
self.stage_tag = "上架中"
print(f"{request.product}此时处于{self.stage_tag}的状态")
self.superior.request_applications(request)
# 经理
class Manager(ProductVerify):
def __init__(self):
self.organ="经理"
def request_applications(self,request:Request):
print(f"{request.product}上架经过了{self.organ}批准!")
self.stage_tag = "在售"
print(f"{request.product}此时处于{self.stage_tag}的状态")
在调用时,需要先对职责链进行组装,然后再来发送相应请求:
# 组装责任链
stockCenter = StockCenter()
salesCenter = SalesCenter()
manager = Manager()
stockCenter.set_superior(salesCenter)
salesCenter.set_superior(manager)
request = Request()
request.product = "香蕉"
stockCenter.request_applications(request)
剩下的就是拼接组装了。