淺析設計模式:裝飾模式(Decorator)

學習裝飾模式之前,我們先來看一個案例:

       大家都喫過蛋糕,但是蛋糕是怎麼做出來的呢?我們不妨這麼猜測:首先蛋糕師會烘焙出一個蛋糕,然後擺上了貨櫃。這時來了一個顧客,他要買奶油蛋糕,蛋糕師會怎麼做 ?最簡單的方式當然是將貨櫃上已經烘焙好的蛋糕取出來,塗上一層奶油,奶油蛋糕就做好了!顧客提出新的需求,例如購買草莓奶油蛋糕,同理只需要在奶油蛋糕的基礎上擺上一些草莓即可。

        上述案例中,將原始蛋糕不斷添加新元素的過程就是裝飾模式,蛋糕師不需要將所有類型的蛋糕全部製作成成品,這樣成本太大,蛋糕師只需要準備好一個烘焙好的蛋糕(被裝飾物)和一些輔料(裝飾邊框),然後根據顧客的需求,往蛋糕上添加輔料即可實現組合口味的蛋糕。編程的過程就像製作蛋糕的過程,我們不可能窮盡所有需求並將其全部實現,但我們能在原始功能的基礎上通過不斷裝飾,使得功能更加明確具體(功能定製化),最後滿足我們的需求。

裝飾模式中的角色:

  • Component:(被裝飾物) 

         增加功能前的核心角色,上述例子中剛烘焙出來的蛋糕就是Component角色,Component只是定義了蛋糕的接口(API)。

  • Concrete Component:(具體的被裝飾物)

       該角色是實現了Component所定義接口的具體的蛋糕,如奶油蛋糕。

  • Decorator:(裝飾物)

        該角色與Component具有相同的接口(API),在它內部保存了被裝飾對象---Component角色。

  • Concrete Decorator:(具體的裝飾物)

      該角色是具體的Decorator。

看到這裏雲裏霧裏?沒關係,我們可以從類圖中理解他們之間的關係:



接下來編程,模擬一個裝飾模式的使用案例!

需求:假設我們需要一個打印字符串的功能

Step One:實現Component角色


    DisPlay表示Component角色,可以理解爲原始蛋糕的角色。它是一個抽象類,代表着"打印字串"的功能,show方法已經提供具體實現,不允許子類重寫(這裏隱含了模板模式)。

Step Two:實現ConcreteComponent角色


      StringDisplay類是Display類的子類,承擔ConcreteComponent角色,可以理解爲具體的蛋糕,如草莓蛋糕。StringDisplay的功能是打印一行字符串。因此getRows方法返回固定值1;getColumns方法返回的是字符串的字符數;getRowText方法只有在行數爲0時才返回字符串。

Step Three:實現Decorator角色


    Border類也是DisPlay類的子類,它表示Decorator角色,可以理解爲做蛋糕的輔料的抽象類,內部含有Display類的實例,該實例表示"被裝飾物",爲什麼打引號?因爲這裏的"被裝飾物"既可能是真正的被裝飾物(原始蛋糕),也可能是已經裝飾了被裝飾物的"中間層被裝飾物"(裝飾了原始蛋糕的奶油蛋糕),哈哈這裏有點拗口,但是應該還是不難理解的大笑就像剝洋蔥,每當剝了一層皮(裝飾物),以爲要發現芯(被裝飾物)了,結果發現還是皮。

Step Four:實現Concrete Decorator角色


    SideBorder是Border類的子類,表示具體的裝飾物(往蛋糕兩側塗奶油生氣),它的功能是在內部this.display打印功能的基礎上,在兩側添加字符,例如this.display打印效果是“hello,world.”,那麼SideBorder實現的打印效果就是“#hello,world.#”。

Step Five:根據需求實現其他的Concrete Decorator角色

    除了上述的SideBorder在兩側添加字符,根據需求可以繼續編寫其他的裝飾物角色,如向上下兩側添加字符等,這裏不贅述了。

Step Final:編寫測試類


    StringDisplay類就是原始的蛋糕,SideBorder類就是在原始蛋糕左右兩側塗上奶油偷笑就是這麼個思想,要想把蛋糕上下左右都塗上奶油怎麼辦?在編寫一個實現上下塗奶油的裝飾物,然後構造實例時,將SideBorder實例作爲參數傳給構造方法就好了!

     裝飾模式就是通過這種不斷的裝飾過程,使得類的功能更加具體更加明確!

java源碼中也有使用裝飾模式的案例:


   Reader就是Component角色,FileReader就是ConcreteComponent角色,而BufferedReader就是ConcreteDecorator角色,FileReader的讀取文件功能經過BufferedReader裝飾使其具有緩存功能...

Ending ...奮鬥

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