背景
小李已经是一个工作一年的初级工程师了,他所在的公司是一家大型购物商场。随着各种网络购物软件兴起,老板也想做一个商场的购物 APP。分给小李的是一个一个订单结算模块,需要支持各种不同的结算策略。
需求
请帮小李写一个订单结算模块,要求支持多种结算策略:
-
原价
-
打 X 折
-
满减,满 X 元减 Y 元
请注意,商品有多种类型,每种类型可能会参与不同的活动,自然需要支持不同的结算策略。
任务
共三个小任务:
- Q1:方案设计。
- Q2:代码实现及结果截图。
- Q3:解释为什么要用这些模式。
要求
要求如下:
- 输入是一揽子商品,输出是最后的订单金额。
- 至少包含两种商品,每种使用不同的结算策略,策略可任选其中一个或两个组合(比如满减 + 打折)。
- 不要实现具体函数或方法的逻辑,可以使用
print
输出功能。
思考
使用策略模式+工厂方法模式
代码实现
from abc import ABCMeta, abstractmethod
from collections import defaultdict
class CashSuper(metaclass=ABCMeta):
@abstractmethod
def accept_cash(self, money):
raise NotImplementedError("not implemented")
# 正常收费
class CashNormal(CashSuper):
def accept_cash(self, money):
return money
# 打折收费
class CashRebate(CashSuper):
def __init__(self, moneyRebateStr="1"):
self.__moneyRebate = float(moneyRebateStr)
def accept_cash(self, money):
return money * self.__moneyRebate
# 返利收费
class CashReturn(CashSuper):
def __init__(self, moneyConditionStr="0", moneyReturnStr="0"):
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 CashRebateAndReturn(CashSuper):
def __init__(self, moneyRebateStr="1", moneyConditionStr="0", moneyReturnStr="0"):
self.__moneyRebate = float(moneyRebateStr)
self.__moneyCondition = float(moneyConditionStr)
self.__moneyReturn = float(moneyReturnStr)
def accept_cash(self, money):
money = money * self.__moneyRebate
if (money >= self.__moneyCondition):
result = money - money // self.__moneyCondition * self.__moneyReturn
return result
class Product(metaclass=ABCMeta):
def __init__(self, product_id, product_name, price):
self.product_id = product_id
self.product_name = product_name
self.price = price
class NormalProduct(Product):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
self.typ = "正常收费"
class RebateProduct(Product):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
self.typ = "打8折"
class ReturnProduct(Product):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
self.typ = "满300返100"
class RebateAndReturnProduct(Product):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
self.typ = "折完减"
class IFactory(metaclass=ABCMeta):
def __init__(self, product_id, product_name, price):
self.product_id = product_id
self.product_name = product_name
self.price = price
@abstractmethod
def create_product(self):
raise NotImplementedError
class NormalProductFactory(IFactory):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
@property
def create_product(self):
return NormalProduct(self.product_id, self.product_name, self.price)
class RebateProductFactory(IFactory):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
@property
def create_product(self):
return RebateProduct(self.product_id, self.product_name, self.price)
class ReturnProductFactory(IFactory):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
@property
def create_product(self):
return ReturnProduct(self.product_id, self.product_name, self.price)
class RebateAndReturnProductFactory(IFactory):
def __init__(self, product_id, product_name, price):
super().__init__(product_id, product_name, price)
@property
def create_product(self):
return RebateAndReturnProduct(self.product_id, self.product_name, self.price)
class CashContext(object):
map_dict = {"正常收费": CashNormal(),
"打8折": CashRebate("0.8"),
"满300返100": CashReturn("300", "100"),
"折完减": CashRebateAndReturn("0.8", "300", "100")
}
def __init__(self, product_dict=None):
self.product_dict = defaultdict(list)
def add_product(self, product):
self.product_dict[product.typ].append(product)
def get_result(self):
result = 0
for typ, product_list in self.product_dict.items():
money = sum([p.price for p in product_list])
result += self.map_dict.get(typ).accept_cash(money)
return result
# 工厂方法模式创建不同的商品 "0":"正常收费","1":"打8折","2":"满300返100","3":"打折满减混合"
# 策略模式计算不同商品的价格
if __name__ == '__main__':
cc = CashContext()
cc.add_product(NormalProductFactory("1", "玫瑰一朵", 1000).create_product)
cc.add_product(RebateProductFactory("2", "玫瑰二朵", 2000).create_product)
cc.add_product(ReturnProductFactory("3", "玫瑰三朵", 3000).create_product)
cc.add_product(RebateAndReturnProductFactory("4", "玫瑰四朵", 4000).create_product)
cc.add_product(RebateProductFactory("5", "玫瑰五朵", 5000).create_product)
cc.add_product(NormalProductFactory("6", "玫瑰六朵", 6800).create_product)
cc.add_product(ReturnProductFactory("7", "玫瑰七朵", 7500).create_product)
cc.add_product(RebateAndReturnProductFactory("8", "玫瑰八朵", 8000).create_product)
print(cc.get_result())