策略模式
(一)、排序问题
大多数问题都可以使用多种方法来解决。以排序问题为例,对于以一定次序把元素放入一个列表,排序算法有很多。通常来说,没有公认最适合所有场景的算法(请参考网页。一些不同的评判标准能帮助我们为不同的场景选择不同的排序算法,其中应该考虑的有以下几个。
- 需要排序的元素数量:这被称为输入大小。当输入较少时,几乎所有排序算法的表现都 很好,但对于大量输入,只有部分算法具有不错的性能。
- 算法的最佳/平均/最差时间复杂度:时间复杂度是算法运行完成所花费的(大致)时间长 短,不考虑系数和低阶项1。这是选择算法的最常见标准,但这个标准并不总是那么充分。
- 算法的空间复杂度:空间复杂度是充分地运行一个算法所需要的(大致)物理内存量。 在我们处理大数据或在嵌入式系统(通常内存有限)中工作时,这个因素非常重要。
- 算法的稳定性:在执行一个排序算法之后,如果能保持相等值元素原来的先后相对次序, 则认为它是稳定的。
- 算法的代码实现复杂度:如果两个算法具有相同的时间/空间复杂度,并且都是稳定的, 那么知道哪个算法更易于编码实现和维护也是很重要的。
(二)、什么是策略模式
策略模式(Strategy pattern)鼓励使用多种算法来解决一个问题,其杀手级特性是能够在运 行时透明地切换算法(客户端代码对变化无感知)。因此,如果你有两种算法,并且知道其中一 种对少量输入效果更好,另一种对大量输入效果更好,则可以使用策略模式在运行时基于输入数 据决定使用哪种算法。
(三)、代码实现
# -*- coding: utf-8 -*-
class FlyBehavior(object): # 定义策略的接口
def __init__(self):
super(FlyBehavior, self).__init__()
# 飞行策略
def fly(self):
pass
# 叫的策略
def quack(self):
pass
class FlyWithWings(FlyBehavior):
'''会飞的鸭子'''
def __init__(self):
super(FlyWithWings, self).__init__()
# 实现具体如何飞行的行为
def fly(self):
print("I'm flying!")
class FlyNoWay(FlyBehavior):
'''不会飞的鸭子'''
def __init__(self):
super(FlyNoWay,self).__init__()
def fly(self):
print("I can't fly!")
class Duck(object):
'''鸭子类'''
def display(self):
pass
# 执行最终的策略
def performFly(self):
print ("I'm a Duck")
self.flyBehavior.fly()
# 策略接收器,这个方法最重要,根据发送过来的策略对象动态决定执行的策略
def setFlyBehavior(self, behavior):
self.flyBehavior = behavior
class MallardDuck(Duck):
def __init__(self):
super(MallardDuck,self).__init__()
self.setFlyBehavior(FlyNoWay()) #发送策略,告诉最终执行器我是一只不会飞的鸭子
def display(self):
print("I'm a real Mallard duck !")
if __name__ == '__main__':
duck = MallardDuck()
duck.performFly()