美文网首页
策略模式与行为参数化

策略模式与行为参数化

作者: tingshuo123 | 来源:发表于2019-03-02 17:06 被阅读0次

    策略模式

    from abc import ABC, abstractclassmethod
    from collections import namedtuple
    
    Customer = namedtuple('Customer', ['name', 'fidelity'])
    
    
    class LineItem:
    
        def __init__(self, product, quantity, price):
            self.product = product
            self.quantity = quantity
            self.price = price
    
        def total(self):
            return self.price * self.quantity
    
    
    class Order:
    
        def __init__(self, customer, cart, promotion=None):
            self.customer = customer
            self.cart = cart
            self.promotion = promotion
    
        def total(self):
            if not hasattr(self, '__total'):
                self.__total = sum(item.total() for item in self.cart)
    
                return self.__total
    
        def due(self):
            if self.promotion is None:
                discount = 0
            else:
                discount = self.promotion.discount(self)
    
            return self.total() - discount
    
        def __repr__(self):
            fmt = '<Order total: {:.2f}> due: {:.2f}>'
            return fmt.format(self.total(), self.due())
    
    
    class Promotion(ABC):
    
        @abstractclassmethod
        def discount(self, order):
            """ 返回折扣金额(非负数) """
    
    
    class FidelityPromo(Promotion):
        """ 为积分为1000或以上的顾客提供5%的折扣 """
    
        def discount(self, order):
            return order.total() * 0.05 if order.customer.fidelity >= 1000 else 0
    
    
    class BulkltemPromo(Promotion):
        """ 单个商品为20个或以上是提供10%折扣 """
    
        def discount(self, order):
            discount = 0
            for item in order.cart:
                if item.quantity >= 20:
                    discount += item.total() * 0.01
    
            return discount
    
    
    class LargeOrderPromo(Promotion):
        """ 订单中不同商品达到10个或以上时提供7%折扣 """
    
        def discount(self, order):
            discount_items = {item.product for item in order.cart}
            if len(discount_items) >= 10:
    
                return order.total() * 0.07
    
            return 0
    

    行为参数化

    from collections import namedtuple
    
    Customer = namedtuple('Customer', ['name', 'fidelity'])
    
    
    class LineItem:
    
        def __init__(self, product, quantity, price):
            self.product = product
            self.quantity = quantity
            self.price = price
    
        def total(self):
            return self.price * self.quantity
    
    
    class Order:
    
        def __init__(self, customer, cart, promotion=None):
            self.customer = customer
            self.cart = cart
            self.promotion = promotion
    
        def total(self):
            if not hasattr(self, '__total'):
                self.__total = sum(item.total() for item in self.cart)
    
                return self.__total
    
        def due(self):
            if self.promotion is None:
                discount = 0
            else:
                discount = self.promotion(self)
    
            return self.total() - discount
    
        def __repr__(self):
            fmt = '<Order total: {:.2f}> due: {:.2f}>'
            return fmt.format(self.total(), self.due())
    
    
    def fidelity_promo(order: Order):
        """ 为积分为1000或以上的顾客提供5%的折扣 """
    
        return order.total() * 0.05 if order.customer.fidelity >= 1000 else 0
    
    
    def bulkltem_promo(order: Order):
        """ 单个商品为20个或以上是提供10%折扣 """
    
        discount = 0
        for item in order.cart:
            if item.quantity >= 20:
                discount += item.total() * 0.01
    
        return discount
    
    
    def large_order_promo(order: Order):
        """ 订单中不同商品达到10个或以上时提供7%折扣 """
    
        discount_items = {item.product for item in order.cart}
        if len(discount_items) >= 10:
    
            return order.total() * 0.07
    
        return 0
    
    

    优化

    自动选择最佳折扣

    将所有折扣函数放在另一个文件中

    # file: promotions.py
    
    from strategy import Order
    
    
    def fidelity_promo(order: Order):
        """ 为积分为1000或以上的顾客提供5%的折扣 """
    
        return order.total() * 0.05 if order.customer.fidelity >= 1000 else 0
    
    
    def bulkltem_promo(order: Order):
        """ 单个商品为20个或以上是提供10%折扣 """
    
        discount = 0
        for item in order.cart:
            if item.quantity >= 20:
                discount += item.total() * 0.01
    
        return discount
    
    
    def large_order_promo(order: Order):
        """ 订单中不同商品达到10个或以上时提供7%折扣 """
    
        discount_items = {item.product for item in order.cart}
        if len(discount_items) >= 10:
    
            return order.total() * 0.07
    
        return 0
    

    添加一个自动获取最佳折扣的函数

    from collections import namedtuple
    import promotions
    import inspect
    
    # inspect.getmembers() 获取模块中的对象
    # 第一个参数是模块名,第二个参数是筛选条件
    # inspect.isfunction 判断对象是否是函数
    promos = [func for name, func in inspect.getmembers(
        promotions, inspect.isfunction)]
    
    Customer = namedtuple('Customer', ['name', 'fidelity'])
    
    
    class LineItem:
    
        def __init__(self, product, quantity, price):
            self.product = product
            self.quantity = quantity
            self.price = price
    
        def total(self):
            return self.price * self.quantity
    
    
    class Order:
    
        def __init__(self, customer, cart, promotion=None):
            self.customer = customer
            self.cart = cart
            self.promotion = promotion
    
        def total(self):
            if not hasattr(self, '__total'):
                self.__total = sum(item.total() for item in self.cart)
    
                return self.__total
    
        def due(self):
            if self.promotion is None:
                discount = 0
            else:
                discount = self.promotion(self)
    
            return self.total() - discount
    
        def __repr__(self):
            fmt = '<Order total: {:.2f}> due: {:.2f}>'
            return fmt.format(self.total(), self.due())
    
    
    def best_promo(order: Order):
        """ 自动选择可用的最佳折扣 """
        return max(promos(order) for promos in promos)
    

    通过以上优化,不仅可以自动选择最佳折扣,如果想添加其他折扣规则,只需要在 promotions.py 文件中添加函数就可以了,不用改动其他的代码。

    相关文章

      网友评论

          本文标题:策略模式与行为参数化

          本文链接:https://www.haomeiwen.com/subject/cjcyuqtx.html