python 实现策略模式

2021-10-21  本文已影响0人  逐风细雨

策略模式

   定义一系列算法,把它们一一封装起来,并且使它们之间可以相互替换。此模式让算法的变化不会影响到使用算法的客户。

"""
实践策略模式
场景:
    订单数量(orders)不同 每一单的单价不同,单量*单价 = 奖金
规则:
    A orders <500 -> 3
    B 500 <= orders <1000 -> 5
    C orders >=1000 -> 6
"""
from collections import namedtuple

sales = namedtuple("sales", ["name", "orders"])


class Rule:
    """
    规则基类
    """

    @property
    def rule_name(self):
        return ""

    def asert_rule(self, orders):
        pass

    def total(self, orders):
        pass


class RuleA(Rule):
    @property
    def rule_name(self):
        return "RuleA"

    def asert_rule(self, orders):
        return orders < 500

    def total(self, orders):
        return orders * 3


class RuleB(Rule):
    @property
    def rule_name(self):
        return "RuleB"

    def asert_rule(self, orders):
        return 500 <= orders < 1000

    def total(self, orders):
        return orders * 5


class RuleC(Rule):
    @property
    def rule_name(self):
        return "RuleC"

    def asert_rule(self, orders):
        return 1000 <= orders

    def total(self, orders):
        return orders * 6


class SelectRule:


    def __init__(self, sales, rule):
        self.sales = sales
        self.rule = rule

    def execute_rule(self):
        name, orders = self.sales.name, self.sales.orders
        if self.rule.asert_rule(orders):
            money = self.rule.total(orders)
            print(f"姓名{name},单量:{orders},适配的规则:{self.rule.rule_name},奖金:{money}")
            return money
        else:
            print(f"姓名{name},单量:{orders},不适配的规则:{self.rule.rule_name}")
            return ""


class MatchSelectRule:
    """
    遍历规则,匹配合适的规则计算奖金
    """

    def __init__(self):
        self.rules = [
            RuleA(),
            RuleB(),
            RuleC(),
        ]

    def execute_rule(self, sales):
        name, orders = sales.name, sales.orders

        for rule in self.rules:
            if rule.asert_rule(orders):
                print(f"姓名{name},单量:{orders},适配的规则:{rule.rule_name},奖金:{rule.total(orders)}")


if __name__ == "__main__":
    a = sales('a', 400)
    b = sales('b', 800)
    c = sales('c', 1500)

    # 单量小于500 传入规则a
    SelectRule(a, RuleA()).execute_rule()
    # 单量800 传入规则a 提示规则不匹配
    SelectRule(b, RuleA()).execute_rule()
    # 自动选择规则
    RuleMap = MatchSelectRule()
    RuleMap.execute_rule(a)
    RuleMap.execute_rule(b)
    RuleMap.execute_rule(c)

执行结果

image.png
上一篇 下一篇

猜你喜欢

热点阅读