策略模式
定义一系列算法,把它们一一封装起来,并且使它们之间可以相互替换。此模式让算法的变化不会影响到使用算法的客户。
- 优点:
- 算法可以自由切换;
- 避免使用多重条件判断;
- 扩展性良好;
- 缺点:
- 每个策略都是一个类,复用的可能性很小;
- 所有策略类都需要对外暴露:调用者得知道有哪些策略
参考文章
"""
实践策略模式
场景:
订单数量(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)
网友评论