最近在读《深入浅出设计模式》这一本书,收获颇多,打算写一个系列的blog,并用python实现其中的每一个设计模式,以加深理解。      

       下面将要介绍的就是书中的第一个设计模式:策略模式

书中以模拟鸭子应用问题作为实例,一款游戏应用中要求有各种各样的鸭子。

       先用继承来实现了这一个应用,其设计如下:

head first python 实战

这个设计主要是以Duck类作为基类,后面所有的鸭子类均以此类派生而来,刚开始在应用还不是很复杂的时候,似乎还没有什么问题,但当派生出来的类(鸭子的类型)越来越多时,问题就出现了。并不是所有的鸭子都会飞的,比如像皮鸭子就不会飞。也不是所有的鸭子都会呱呱叫,也有鸭子吱吱叫。也许你会说,我可以在派生类中重写基类的方法,从而达到应用的要求,实现不同的鸭子有不同的叫法,不同的飞行方式。但是有一个问题不能解决,重写函数并不应该改变原有函数的行为,比如fly()这个函数,不能飞的鸭子就不应该有fly()这个函数存在。而如果我们只是重写基类的fly()函数,看起来是不合适的。并且quack()函数用于发出“呱呱叫”,而基类中定义了quack()就意味着所有的鸭子中都有quck(),如果现在要求鸭子“吱吱叫”,怎么办呢?在基类中添加一个"吱吱叫“的函数?那这样又会影响到其它的子类。

        如此看来,派生并不解决问题最好的办法,或者说不能只用派生来解问题。

        分析一下,得到以下设计原则:

  • 针对接口编程,而不是实现编程

  • 分离应用中经常变化的部分

head first python 实战

最终,我们分开了易于变化的部分,飞行行为和呱呱叫行为,设计出来的类图如下:

head first python 实战

head first python 实战

我用python代码实现如下:

''' 

The first Design Pattern: 

    Strategy Pattern.

KeyNote:

    Identify the aspects of your application that vary and separate them 

    from what stays the same.

'''


class FlyBehavior:

    ''' Interface class: FlyBehavior '''

    def fly(self):

        return


class FlyWithWing(FlyBehavior):

    def fly(self):

      print 'I am flying with wings!'


class FlyNoWay(FlyBehavior):

    def fly(self):

        print 'I cannot fly!'


class QuackBehavior:

    ''' Interface Behavior: QuackBehavior '''

    def quack(self):

        return

class Quack(QuackBehavior):

    def quack(self):

        print 'Quack!'


class Squeak(QuackBehavior):

    def quack(self):

        print 'Squeak'


class MuteQuack(QuackBehavior):

    def quack(self):

        print 'MuteQuack'


class Duck:

    '''Base class: Duck. All ducks are inherent from this class'''

    def __init__(self, flyParam, quackParam):

        self.flyBehavior = flyParam

        self.quackBehavior = quackParam

    def performFly(self):

        self.flyBehavior.fly()

    def performQuack(self):

        self.quackBehavior.quack()

    def swim(self):

        print 'All ducks can swim...'

        return 

    def display(self):

        return


class RedDuck(Duck):

    def __init__(self, flyParam=FlyWithWing(), quackParam=MuteQuack()):

        Duck.__init__(self, flyParam, quackParam)

    def display(self):

        print 'I am a red duck!'

        return


class RubberDuck(Duck):

    def __init__(self, flyParam=FlyNoWay(), quackParam=Quack()):

        Duck.__init__(self, flyParam, quackParam)

    def display(self):

        print 'I am a rubber duck!'


duck = RedDuck()

duck.display()

duck.performFly()

duck.performQuack()

duck.swim()


duck = RubberDuck()

duck.display()

duck.performFly()

duck.performQuack()

duck.swim()



转载于:https://my.oschina.net/zilinangel1986/blog/282932

相关文章: