小雪崩 发表于 2017-5-6 10:43:21

Head First 设计模式——策略模式(Strategy Pattern)——Python实现

  本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 Unported许可协议进行许可。允许非商业转载,但应注明作者及出处。

作者:liuyuan_jq
2011-06-13



策略模式定义
  定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

问题
J o e 上班的公司做了一套相当成功的模拟鸭子游戏: SimUDuck。游戏中会出现各种鸭子,一边游泳戏水,一边呱 呱叫。此系统的内部设计使用了标准的OO技术,设计了一个鸭 子超类(Superclass),并让各种鸭子继承此超类。
设计原则

[*]找出应用中可能需要变化之处,把它 们独立出来,不要和那些不需要变化 的代码混在一起。
[*]针对接口编程,而不是针对实现编程
[*]多用组合,少用继承
设计鸭子的行为
  我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变。为了要把这两个行为从Duck类中分开,我们将把它们从Duck类 中取出来,建立一组新类来代表每个行为。这样,鸭子类就不再需要知道行为的实现细节。
  class Duck(object):"""Duck接口类"""def __init__(self):super(Duck, self).__init__()def setFlyBehavior(self, flyBehavior):self.flyBehavior = flyBehavior;def setQuackBehavior(self, quackBehavior):self.quackBehavior = quackBehaviordef display(self):raise NotImplementedError("abstract duck")def performFly(self):self.flyBehavior.fly();def performQuack(self):self.quackBehavior.quack();def swim(self):print("All ducks float, even decoys!")
设计鸭子的飞行行为
  class FlyBehavior(object):"""飞行行为接口类"""def fly(self):raise NotImplementedError("abstract FlyBehavior")
设计鸭子的叫行为
  class QuackBehavior(object):def quack(self):raise NotImplementedError("abstract QuackBehavior")
实现源码
  flyBehavior.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-class FlyBehavior(object):"""飞行行为接口类"""def fly(self):raise NotImplementedError("abstract FlyBehavior")class FlyWithWings(FlyBehavior):def fly(self):print("I'm flying!!");class FlyNoWay(FlyBehavior):def fly(self):print("I can't fly");class FlyRocketPowered(FlyBehavior):def fly(self):print("I'm flying with a rocket");
  

  quackBehavior.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-class QuackBehavior(object):def quack(self):raise NotImplementedError("abstract QuackBehavior")class Quack(QuackBehavior):def quack(self):print("Quack");class FakeQuack(QuackBehavior):def quack(self):print("Qwak");class MuteQuack(QuackBehavior):def quack(self):print("<< Silence >>")class Squeak(QuackBehavior):def quack(self):print("Squeak");
  duck.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from flyBehavior import *from quackBehavior import *class Duck(object):"""Duck接口类"""def __init__(self):super(Duck, self).__init__()def setFlyBehavior(self, flyBehavior):self.flyBehavior = flyBehavior;def setQuackBehavior(self, quackBehavior):self.quackBehavior = quackBehaviordef display(self):raise NotImplementedError("abstract duck")def performFly(self):self.flyBehavior.fly();def performQuack(self):self.quackBehavior.quack();def swim(self):print("All ducks float, even decoys!")class DecoyDuck(Duck):"""诱饵鸭"""def __init__(self):super(DecoyDuck, self).__init__()self.setFlyBehavior(FlyNoWay())self.setQuackBehavior(MuteQuack())def display(self):print("I'm a duck Decoy")class MallardDuck(Duck):"""绿头鸭"""def __init__(self):super(MallardDuck, self).__init__()self.setFlyBehavior(FlyWithWings())self.setQuackBehavior(Quack())def display(self):print("I'm a real Mallard duck")class RedHeadDuck(Duck):"""红头鸭"""def __init__(self):self.setFlyBehavior(FlyWithWings())self.setQuackBehavior(Quack())def display(self):print("I'm a real Red Headed duck")class ModelDuck(Duck):"""模型鸭"""def __init__(self):self.setFlyBehavior(FlyNoWay())self.setQuackBehavior(Quack())def display(self):print("I'm a model duck")class RubberDuck(Duck):"""橡皮鸭"""def __init__(self):self.setFlyBehavior(FlyNoWay())self.setQuackBehavior(Squeak())def display(self):print("I'm a rubber duckie")if __name__ == "__main__":mallard      = MallardDuck()rubberDuckie = RubberDuck()decoy      = DecoyDuck()model      = ModelDuck()# 鸭子quackmallard.performQuack()rubberDuckie.performQuack()decoy.performQuack()# 动态改变鸭子的fly行为model.performFly()model.setFlyBehavior(FlyRocketPowered())model.performFly()# 绿头鸭的 quack and flymallard = MallardDuck()mallard.performQuack()mallard.performFly()
执行结果
  QuackSqueak<< Silence >>I can't flyI'm flying with a rocketQuackI'm flying!!
  
页: [1]
查看完整版本: Head First 设计模式——策略模式(Strategy Pattern)——Python实现