问题
基于商场促销,实现一个简单的商场收银软件,比如商场有原价,打5折,6折,7折;满300减100,满200减50等各种促销方式,使用设计模式以及面向对象的设计模式,设计程序使得程序具有更好的鲁棒性。
问题分析
该问题可以使用Python下的设计模式学习(1)——简单工厂类来实现,即将打折,满减分别作为一个类进行封装,再在工厂类对这些类进行统一判断进行实例化判断。但是这是有弊端的,主要表现在当商场要经常改动对应的满减或者打折的额度时,用户需要在工厂类中进行大量的修改,这显然不符合我们面向对象的设计原则。这里使用
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
商场收银时如何促销,用打折还是返利,其实都是算法,算法本身上是一种策略,最重要的是这些算法是随时可以互相替换的,这就是变换点,而封装变换点是我们面向对象的一种很重要思维方式。下面我将介绍基于本问题的策略模式的结构图和基本代码。
UML图
代码示例
'''
创建时间:2021/3/8
创建者:zhongbin
创建任务:使用策略模式解决商场销售问题
'''
###所有销售策略的父类
class CashSuper:
# def __int__(self,Price):
# self.Price=Price
def acceptCash(self,money):
pass
###编写不同销售策略的不同类
#原价类
class CashNormal(CashSuper):
def acceptCash(self,money):
return money
#折扣类:打bate*10折
class CashRebate(CashSuper):
def __init__(self,bate=1):
self.bate=bate
def acceptCash(self,money):
if self.bate>0:
return money*self.bate
else:
return "err"
#满减类:满cash减recash
class CashReturn(CashSuper):
def __init__(self,cash,recash):
self.cash=cash
self.recash=recash
def acceptCash(self,money):
if money>self.cash:
return money-self.recash
else:
return money
###设计一个处理类对上述的不同的策略类进行处理
class CashContext:
def __init__(self,cash_object):
self.cash=cash_object
def GetResult(self,money):
return self.cash.acceptCash(money)
#主程序
if __name__=="__main__":
str="打8折"
cash=CashSuper()
if str=="原价":
cash=CashNormal()
cc=CashContext(cash)
# cc=CashContext(CashNormal())
elif str=="满300减100":
cc=CashContext(CashReturn(300,100))
elif str=="打8折":
cc=CashContext(CashRebate(0.8))
print("本次消费为:")
print(cc.GetResult(100))
上述程序主有一不好的点在于关于程序的判断是设计在主程序中,但是按照封装的原则,用户代码只需要知道的字符,比如“打8折”“满300减100”,然后程序内部完成对应的运算,所以可以对CashContext类进行一些修改,改成(1)中类似的简单工厂类的形式。
class CashContextFactory:
def CreateCashObeject(self,str):
if str=="原价":
return CashNormal()
elif str=="打8折":
return CashRebate(0.8)
elif str=="满300减100":
return CashReturn(300,100)
#主程序
if __name__=="__main__":
str="打8折"
# cash=CashSuper()
# if str=="原价":
# cash=CashNormal()
# cc=CashContext(cash)
# # cc=CashContext(CashNormal())
# elif str=="满300减100":
# cc=CashContext(CashReturn(300,100))
# elif str=="打8折":
# cc=CashContext(CashRebate(0.8))
# print("本次消费为:")
# print(cc.GetResult(100))
cashobject=CashContextFactory().CreateCashObeject(str)
print(cashobject.acceptCash(100))
可以刊出后主函数的有关销售的代码段操作会更短。