11.設計模式之九:裝飾模式【結構型模式】

定義與特色

裝飾(Decorator)模式的定義:指在不改變現有對象結構的狀況下,動態地給該對象增長一些職責(即增長其額外功能)的模式,它屬於對象結構型模式。python

裝飾(Decorator)模式的主要優勢有:spa

  • 採用裝飾模式擴展對象的功能比採用繼承方式更加靈活。
  • 能夠設計出多個不一樣的具體裝飾類,創造出多個不一樣行爲的組合。

 其主要缺點是:裝飾模式增長了許多子類,若是過分使用會使程序變得很複雜。設計

結構與實現

一般狀況下,擴展一個類的功能會使用繼承方式來實現。但繼承具備靜態特徵,耦合度高,而且隨着擴展功能的增多,子類會很膨脹。code

若是使用組合關係來建立一個包裝對象(即裝飾對象)來包裹真實對象,並在保持真實對象的類結構不變的前提下,爲其提供額外的功能,這就是裝飾模式的目標。component

下面來分析其基本結構和實現方法:對象

1. 模式的結構

裝飾模式主要包含如下角色。blog

  • 抽象構件(Component)角色:定義一個抽象接口以規範準備接收附加責任的對象。
  • 具體構件(Concrete    Component)角色:實現抽象構件,經過裝飾角色爲其添加一些職責。
  • 抽象裝飾(Decorator)角色:繼承抽象構件,幷包含具體構件的實例,能夠經過其子類擴展具體構件的功能。
  • 具體裝飾(ConcreteDecorator)角色:實現抽象裝飾的相關方法,並給具體構件對象添加附加的責任。

2. 模式的實現

裝飾模式的實現代碼以下:繼承

class Component(object):
    def operation(self):
        pass

class ConcreteComponent(Component):
    def operation(self):
        print('ConcreteComponent')

class Decorator(Component):
    __component = None

    def __init__(self, component):
        self.__component = component

    def operation(self):
        self.__component.operation()

class ConcreteDecorator(Decorator):
    def __init__(self, component):
        super().__init__(component)

    def operation(self):
        super().operation()
        self.added_function()

    def added_function(self):
        print("add contents")

if __name__ == '__main__':
    p = ConcreteComponent()
    p.operation()

    print('----------------------add something-------------------')
    d = ConcreteDecorator(p)
    d.operation()

應用實例

用裝飾模式實現遊戲角色「莫莉卡·安斯蘭」的變身。接口

分析:在《惡魔戰士》中,遊戲角色「莫莉卡·安斯蘭」的原身是一個可愛少女,但當她變身時,會變成頭頂及背部延伸出蝙蝠狀飛翼的女妖,固然她還能夠變爲穿着漂亮外衣的少女。遊戲

這些均可用裝飾模式來實現,在本實例中的「莫莉卡」原身有 setImage(String t) 方法決定其顯示方式,而其 變身「蝙蝠狀女妖」和「着裝少女」能夠用 setChanger() 方法來改變其外觀,原身與變身後的效果用 display() 方法來顯示,

圖所示是其結構圖。

class Morrigan(object):
    def display(self):
        pass

class Original(Morrigan):
    def display(self):
        print('Original Morrigan')

class Changer(Morrigan):
    __original = None
    def __init__(self, original):
        self.__original = original

    def display(self):
        self.__original.display()

class Succybus(Changer):
    def __init__(self, original):
        super().__init__(original)

    def set_changer(self):
        print('Succybus Morrigan')

    def display(self):
        super().display()
        print('↓↓↓↓↓↓↓↓↓↓↓')
        self.set_changer()

class Girl(Changer):
    def __init__(self, original):
        super().__init__(original)

    def set_changer(self):
        print('Girl Morrigan')

    def display(self):
        super().display()
        print('↓↓↓↓↓↓↓↓↓↓↓')
        self.set_changer()

if __name__ == '__main__':
    o = Original()
    o.display()

    s = Succybus(o)
    s.display()

    g = Girl(o)
    g.display()

應用場景

前面講解了關於裝飾模式的結構與特色,下面介紹其適用的應用場景,裝飾模式一般在如下幾種狀況使用。

  • 當須要給一個現有類添加附加職責,而又不能採用生成子類的方法進行擴充時。例如,該類被隱藏或者該類是終極類或者採用繼承方式會產生大量的子類。
  • 當須要經過對現有的一組基本功能進行排列組合而產生很是多的功能時,採用繼承關係很難實現,而採用裝飾模式卻很好實現。
  • 當對象的功能要求能夠動態地添加,也能夠再動態地撤銷時。

模式的擴展

裝飾模式所包含的 4 個角色不是任什麼時候候都要存在的,在有些應用環境下模式是能夠簡化的,如如下兩種狀況。

(1) 若是隻有一個具體構件而沒有抽象構件時,可讓抽象裝飾繼承具體構件,其結構圖如圖所示。

(2) 若是隻有一個具體裝飾時,能夠將抽象裝飾和具體裝飾合併,其結構圖如圖所示。

相關文章
相關標籤/搜索