本作品采用知识共享署名-非商业性使用-相同方式共享 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 = quackBehavior def 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 = quackBehavior def 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() # 鸭子quack mallard.performQuack() rubberDuckie.performQuack() decoy.performQuack() # 动态改变鸭子的fly行为 model.performFly() model.setFlyBehavior(FlyRocketPowered()) model.performFly() # 绿头鸭的 quack and fly mallard = MallardDuck() mallard.performQuack() mallard.performFly()
执行结果
Quack Squeak << Silence >> I can't fly I'm flying with a rocket Quack I'm flying!!
本文介绍了一种软件设计模式——策略模式,通过将算法封装为独立的对象,使得这些算法可以在运行时互换。文中详细展示了如何利用该模式设计一个模拟鸭子游戏的例子,并提供了具体的Python代码实现。
1925

被折叠的 条评论
为什么被折叠?



