策略模式(Strategy Pattern):
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
原则:
针对接口(即超类型)编程,而不是针对实现编程;
把会变化的部分取出并“封装”起来,好让其它部分不会受到影响;
多用组合,少用继承;
案例:
现在需要实现几种鸭子,每种鸭子都有不同的特征(display)、飞行方式(fly)和发声方式(quack);
首先我们需要建一个鸭子超类(Duck),然后在各种鸭子子类(MallardDuck, RedheadDuck, RubberDuck, DecoyDuck)中实现对应的方法;
每种鸭子的外观都不一样,因此display可留到子类中实现,即每增加一种鸭子类型,都必须重写一次display方法;
但是飞行和发声的方式就那么几种,如果按照display的方式处理,即便有些鸭子类型具有相同的行为方式也需要逐个重写,就会有大量重复代码;
如果采用继承方式,继承的子类如果相同则不用重写,但是不同的还是要重写,仍然没解决问题;
按照策略模式的原则,我们应该将行为方式当作独立算法看待,从鸭子类中独立出来,并提供统一接口;
这样的话,以后增加算法以及将某类鸭子和某种行为绑定会变得很容易;
代码:
#!/usr/bin/python
class Duck:
def display(self):
pass
def setFlyBehavior(self,fb):
self.flyBehavior = fb
def setQuackBehavior(self,qb):
self.quackBehavior = qb
def performQuack(self):
self.quackBehavior.quack()
def performFly(self):
self.flyBehavior.fly()
class FlyBehavior:
def fly(self):
pass
class FlyWithWings(FlyBehavior):
def fly(self):
print "Fly with wings."
class FlyNoWay(FlyBehavior):
def fly(self):
print "Fly no way."
class QuackBehavior:
def quack(self):
pass
class Quack(QuackBehavior):
def quack(self):
print "gua gua"
class Squeak(QuackBehavior):
def quack(self):
print "zhi zhi"
class MuteQuack(QuackBehavior):
def quack(self):
print "nothing"
class MallardDuck(Duck):
def __init__(self):
self.setFlyBehavior(FlyWithWings())
self.setQuackBehavior(Squeak())
def display(self):
print "MallardDuck"
class RedheadDuck(Duck):
def __init__(self):
self.setFlyBehavior(FlyWithWings())
self.setQuackBehavior(Quack())
def display(self):
print "RedheadDuck"
class RubberDuck(Duck):
def __init__(self):
self.setFlyBehavior(FlyNoWay())
self.setQuackBehavior(MuteQuack())
def display(self):
print "RubberDuck"
class DecoyDuck(Duck):
def __init__(self):
self.setFlyBehavior(FlyWithWings())
self.setQuackBehavior(MuteQuack())
def display(self):
print "DecoyDuck"
for n in MallardDuck(),RedheadDuck(),RubberDuck(),DecoyDuck():
n.display()
n.performFly()
n.performQuack()
n.setFlyBehavior(FlyNoWay())
n.setQuackBehavior(Quack())
n.display()
n.performFly()
n.performQuack()
输出:
MallardDuck
Fly with wings.
zhi zhi
RedheadDuck
Fly with wings.
gua gua
RubberDuck
Fly no way.
nothing
DecoyDuck
Fly with wings.
nothing
DecoyDuck
Fly no way.
gua gua
参考:
《Head First 设计模式》