问题

基于商场促销,实现一个简单的商场收银软件,比如商场有原价,打5折,6折,7折;满300减100,满200减50等各种促销方式,使用设计模式以及面向对象的设计模式,设计程序使得程序具有更好的鲁棒性。

问题分析

该问题可以使用Python下的设计模式学习(1)——简单工厂类来实现,即将打折,满减分别作为一个类进行封装,再在工厂类对这些类进行统一判断进行实例化判断。但是这是有弊端的,主要表现在当商场要经常改动对应的满减或者打折的额度时,用户需要在工厂类中进行大量的修改,这显然不符合我们面向对象的设计原则。这里使用
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
商场收银时如何促销,用打折还是返利,其实都是算法,算法本身上是一种策略,最重要的是这些算法是随时可以互相替换的,这就是变换点,而封装变换点是我们面向对象的一种很重要思维方式。下面我将介绍基于本问题的策略模式的结构图和基本代码。

UML图

Python计算折扣500打9折 python商场打折问题_工厂类

代码示例

'''
创建时间: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))

可以刊出后主函数的有关销售的代码段操作会更短。