使用“策略”模式结合一等函数与装饰器实现简单网购结算系统

练习:使用装饰器优化一等函数实现策略

我们可以实现:

  1. 商品点单

  2. 使用“策略”模式实现折扣,并利用装饰器Promo

  3. 推荐最佳折扣,利用Promo装饰器带来的好处

实现商品类


from collections import namedtuple

Order = namedtuple('Order', ['name', 'dots'])

Trr = namedtuple('Trr', ['name', 'price'])

class Cash:



    """实现结算"""



    def __init__(self, order, cater, using_promo=None):

        self.order = order

        self.cater = cater

        self.promo = using_promo

    def total(self):

        self.total_price = 0

        for item in self.cater:

            self.total_price += item.price

        return self.total_price



    def due(self):

        return self.total_price - self.promo(self.order, self.cater, self.total_price)



    def __repr__(self):

        self.total()

        rep = '===顾客信息===\n'

        rep += '购买人名称: {}\n'.format(self.order.name)

        rep += '===商品===\n'

        for item in self.cater:

            rep += '品名: {}    价格: {}\n'.format(item.name, item.price)

        rep += '===结算===\n'

        rep += '总价:{}\n'.format(self.total_price)

        rep += '优惠后价格:{}'.format(self.due())

        return rep

使用“策略”模式实现折扣,加入了一个全新的装饰器:promo。


# 一个用来存储打折函数的列表

promos = []

def promo(promo_func):

    """打折函数装饰器"""

    promos.append(promo_func)

    return promo_func

@promo    # 它是一个折扣函数

def dot_promo(order, cater, total_price):

    """如果用户点数高于100,就给予8折(1-0.8)"""

    if order.dots >= 100:

        return total_price * 0.2

    else:

        return 0

@promo    # 它是一个折扣函数

def half_past_promo(order, cater, total_price):

    """简单地给予一个5折"""

    return total_price * 0.5

@promo    # 它是一个折扣函数

def up_ten_promo(order, cater, total_price):

    """如果购物车内商品满或多于10个,则给予7.5折优惠"""

    if len(cater) >= 10:

        return total_price * 0.25

    else:

        return 0

推荐最佳折扣


def best_promo(order, cater, total):

    """找到并推荐最佳折扣,按最佳折扣计算"""

    return max(found_promo(order, cater, total) for found_promo in promos)    # 试验每一个优惠,使用最好的结果

开始!试验我们的代码。


# 例子一:Ben买了一个sock, 享用积分消费。

ben = Order('Ben', 1000)

ben_cash = Cash(order=ben, cater=[Trr('sock', 30), ], using_promo=dot_promo)

print(ben_cash, '\n')

# 例子二:Sally买了一个milk, 享用五折优惠。

sally = Order('Sally', 1000)

sally_cash = Cash(order=sally, cater=[Trr('milk', 25), ], using_promo=half_past_promo)

print(sally_cash, '\n')

# 例子三:我双十一买了一堆东西,享用智能优惠。

msu = Order('Su', 1000)

su_cash = Cash(order=msu, cater=[Trr('sth', 130), Trr('sth', 130), Trr('sth', 130), ], using_promo=best_promo)

print(su_cash, '\n')

# 例子四:XiaoMing双十二买了一堆东西,享用满十7.5折优惠。

ming = Order('XiaoMing', 1000)

ming_cash = Cash(order=ming, cater=[Trr('sth', 130), Trr('sth', 130), Trr('sth', 130),

                                    Trr('sth', 130), Trr('sth', 130), Trr('sth', 130),

                                    Trr('sth', 130), Trr('sth', 130), Trr('sth', 130), ], using_promo=dot_promo)

print(ming_cash, '\n')

输出

    ===顾客信息===

    购买人名称: Ben

    ===商品===

    品名: sock    价格: 30

    ===结算===

    总价:30

    优惠后价格:24.0



    ===顾客信息===

    购买人名称: Sally

    ===商品===

    品名: milk    价格: 25

    ===结算===

    总价:25

    优惠后价格:12.5



    ===顾客信息===

    购买人名称: Su

    ===商品===

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    ===结算===

    总价:390

    优惠后价格:195.0



    ===顾客信息===

    购买人名称: XiaoMing

    ===商品===

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    品名: sth    价格: 130

    ===结算===

    总价:1170

    优惠后价格:936.0

这个程序的灵感来源于O'Reilly Media的书《流畅的Python》,作者是巴西的Luciano Ramalho。

你可能感兴趣的:(使用“策略”模式结合一等函数与装饰器实现简单网购结算系统)