设计模式:策略模式(Python)

时间:2022-04-19 22:00:53

策略模式(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()
print

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 设计模式》