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

本文介绍了一种软件设计模式——策略模式,通过将算法封装为独立的对象,使得这些算法可以在运行时互换。文中详细展示了如何利用该模式设计一个模拟鸭子游戏的例子,并提供了具体的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 = 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!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值