深入淺出設計模式python版——策略模式(stratery)

書中第一個設計模式是策略模式:

書中以模擬鴨子應用問題作爲實例,一款遊戲應用中要求有各種各樣的鴨子。

       先用繼承來實現了這一個應用,其設計如下:



        這個設計主要是以Duck類作爲基類,後面所有的鴨子類均以此類派生而來,剛開始在應用還不是很複雜的時候,似乎還沒有什麼問題,但當派生出來的類(鴨子的類型)越來越多時,問題就出現了。並不是所有的鴨子都會飛的,比如像皮鴨子就不會飛。也不是所有的鴨子都會呱呱叫,也有鴨子吱吱叫。也許你會說,我可以在派生類中重寫基類的方法,從而達到應用的要求,實現不同的鴨子有不同的叫法,不同的飛行方式。但是有一個問題不能解決,重寫函數並不應該改變原有函數的行爲,比如fly()這個函數,不能飛的鴨子就不應該有fly()這個函數存在。而如果我們只是重寫基類的fly()函數,看起來是不合適的。並且quack()函數用於發出“呱呱叫”,而基類中定義了quack()就意味着所有的鴨子中都有quck(),如果現在要求鴨子“吱吱叫”,怎麼辦呢?在基類中添加一個"吱吱叫“的函數?那這樣又會影響到其它的子類。

        如此看來,派生並不解決問題最好的辦法,或者說不能只用派生來解問題。

        分析一下,得到以下設計原則:

  • 針對接口編程,而不是實現編程
  • 分離應用中經常變化的部分


最終,我們分開了易於變化的部分,飛行行爲和呱呱叫行爲,設計出來的類圖如下:

————————————————————我是pythonic的分割線——————————————————————————

參考這位大哥pytonic的設計模式代碼(https://github.com/faif/python-patterns),我的代碼改造如下:

# -*- coding:utf-8 -*-
#Duck.py
import types
import QuackBehavior
import FlyBehaviour
class Duck:
    def __init__(self,concreteQuack=None, concreteFly=None):
        if (concreteQuack is not None):
            self.quackBehavior = types.MethodType(concreteQuack,self)
        if(concreteFly is not None):
            self.flyBehaviour = types.MethodType(concreteFly,self)

    def quackBehaviour(self):
        print "normal quack"
    def flyBehaviour(self):
        print "nomal fly"
    def performQuack(self):
        self.quackBehaviour()
    def performFly(self):
        self.flyBehaviour()


# class RedHeadDuck(Duck):
#     def __init__(self):
#         Duck.__init__(self,QuackBehavior.sQuack(), FlyBehaviour.flyWithWing())
#
# class RubberDuck(Duck):
#     def __init__(self):
#         Duck.__init__(self, QuackBehavior.muteQuack(), FlyBehaviour.flyNoWay())



if __name__ == "__main__":
    redHeadDuck = Duck(QuackBehavior.sQuack, FlyBehaviour.flyWithWing)
    rubberDuck = Duck(QuackBehavior.muteQuack, FlyBehaviour.flyNoWay)

    print "---1"
    redHeadDuck.performFly()
    redHeadDuck.performQuack()

    print "----2"
    rubberDuck.performFly()
    rubberDuck.performQuack()







# -*- coding:utf-8 -*-
#QuackBehaviour.py

def quack(self):
    print "quack!"

def sQuack(self):
    print "sQuack!"

def muteQuack(self):
    print "muteQuack!"

# -*- coding:utf-8 -*-
#FlyBehaviour.py
def flyWithWing(self):
    print "flyWithWing!"

def flyNoWay(self):
    print "flyNoWay!"



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章