“Head First 設計模式“ :裝飾模式
裝飾模式
裝飾者模式:動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。
裝修模式的角色如下:
抽象構件角色(Component):給出一個抽象介面,以規範準備接收附加責任的物件。
具體構件角色(Concrete Component):定義將要接收附加責任的類。
裝飾角色(Decorator):持有一個構件(Component)物件的引用,並定義一個與抽象構件介面一致的介面。
具體裝飾角色(Concrete Decorator):負責給構件物件“貼上”附加的責任。類圖如下:
裝修模式的特點:
裝飾物件和真實物件有相同的介面。這樣客戶端物件就可以以和真實物件相同的方式和裝飾物件互動。
裝飾物件包含一個真實物件的引用(reference)。
裝飾物件接收所有來自客戶端的請求,它把這些請求轉發給真實的物件。
裝飾物件可以在轉發這些請求之前或之後附加一些功能。
這樣就確保了在執行時,不用修改給定物件的結構就可以在外部增加附加的功能。
裝修模式的缺點:
裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜。
裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出較佳選擇。
裝飾模式的使用場景:
適合對預設目標實現中的多個介面進行排列組合排程
適合對預設目標實現進行選擇性擴充套件
適合對預設目標實現未知或者不易擴充套件的情況。
例項1:咖啡店有好幾種咖啡,每一種都是自己的價格,成分等,類圖如下;
問題的產生:咖啡可以放些糖等調料,調料種類多,新增了N個子類來對應咖啡,價格,調料之間的關係,後期維護有了很大的挑戰,類圖如下:
解決:我們可以用裝飾模式來解決,最終的類圖如下:
例項2:擴充套件JAVA裡的I/O,讀取檔案裡的資料,並轉成大寫字母輸出
分析:JDK裡I/O框架用到了介面卡模式,類圖如下:
說明:抽象構建角色(InputStream),裝飾角色(FilterInputStream),具體裝飾(BufferdInputStream等),具體構建角色(FileInputStream等)
實現:我們看類圖,我們繼承FilterInputStream,覆蓋掉read方法就能滿足這個需求了。
設計原則:類應該對擴充套件開放,對修改關閉。
轉載於:https://blog.51cto.com/u2r2otkit/2103122