策略模式

定义

定义一系列算法,把他们封装起来,并且可以相互替换使用,使得算法可以独立于客户端而变化。

适用性

  • 许多相关类仅仅只有算法不同
  • 需要使用使用一个算法的不用变体
  • 算法使用客户不应该知道的数据
  • 一个类定义了多种行为

优缺点

  • 一系列可重用的算法或者行为
  • 一种替代继承的方法
  • 消除一些条件语句
  • 可以选择不同的行为或者算法
  • 客户端要知道策略的不同地方

实现

年底了,需要发年终奖,年终奖需要根据本年度的绩效来决定拿多少,绩效的等级有 S、A、B 三种。 实现一个计算每个人年终奖的程序,后期可能会添加 S+、C 等级或者更多。

Python Class

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 定义一系列计算年终奖的算法
bouns_strategy = {
    'S': lambda s: s * 4,
    'A': lambda s: s * 3,
    'B': lambda s: s * 2,

    # 添加 S+ 和 C 算法
    'SP': lambda s: s * 5,
    'C': lambda s: s ,
}


class Bouns:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        # 计算方法通过属性来设定,这样可以容易被替换
        self.calculate = None

    def __str__(self):
        return "{} get {}".format(self.name, self.bouns)

    @property
    def bouns(self):
        return self.calculate(self.salary)


if __name__ == '__main__':
    jack_bouns = Bouns('jack', 10000)
    jack_bouns.calculate = bouns_strategy['S']
    print(jack_bouns)

    linda_bouns = Bouns('linda', 10000)
    linda_bouns.calculate = bouns_strategy['A']
    print(linda_bouns)

    sean_bouns = Bouns('sean', 10000)
    sean_bouns.calculate = bouns_strategy['B']
    print(sean_bouns)

    # 现在需求变化了,添加 S+ 作为最高级,C 级 作为最低级
    # jack 从 S 调整到 S+
    # sean 从 B 调整到 C
    print('需求改变以后......')

    jack_bouns.calculate = bouns_strategy['SP']
    print(jack_bouns)

    print(linda_bouns)

    sean_bouns.calculate = bouns_strategy['C']
    print(sean_bouns)

    # 从上面的计算年终的算法可以看出
    # 需求改变以后只需要替代原来算法就可实现了

Python Function

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 定义一系列计算年终奖的算法
bouns_strategy = {
    'S': lambda s: s * 4,
    'A': lambda s: s * 3,
    'B': lambda s: s * 2,

    # 添加 S+ 和 C 算法
    'SP': lambda s: s * 5,
    'C': lambda s: s,
}


def calculate_bouns(name, strategy, salary):
    return '{name} get {salary}'.format(name=name, salary=strategy(salary))


if __name__ == '__main__':
    print(calculate_bouns('jack', bouns_strategy['S'], 10000))
    print(calculate_bouns('linda', bouns_strategy['A'], 10000))
    print(calculate_bouns('sean', bouns_strategy['B'], 10000))

    # 现在需求变化了,添加 S+ 作为最高级,C 级 作为最低级
    # jack 从 S 调整到 S+
    # sean 从 B 调整到 C
    print('需求改变以后......')

    print(calculate_bouns('jack', bouns_strategy['SP'], 10000))
    print(calculate_bouns('linda', bouns_strategy['A'], 10000))
    print(calculate_bouns('sean', bouns_strategy['C'], 10000))