本文實例講述了Java基於裝飾者模式實現的染色饅頭案例。分享給大家供大家參考,具體如下:
一、模式定義
裝飾者模式,是在不改變原類文件和使用繼承的情況下,動態擴展一個對像功能,它是通過創建一個包裝對象,也就是裝飾來包裝真實的對象。
裝飾對象和真實對像有相同接口,這樣客戶端對象就可以和真實對象相同方式和裝飾對象交互。
裝飾對象包含一個真實對象的引用。
二、模式舉例
1. 模式分析
我們藉用黑心商販製做染色饅頭案例說明這一模式。
2. 裝飾者模式靜態類圖
3. 代碼示例
3.1 創建饅頭接口――IBread
package com.demo.abs;/** * 饅頭加工接口* * @author * */public interface IBread { // 準備材料public void prepair(); // 和麵public void kneadFlour(); // 蒸饅頭public void steamed(); /** * 加工饅頭方法*/ public void process();}3.2 正常饅頭實現――NormalBread
package com.demo.abs;/** * 正常饅頭的實現* * @author * */public class NormalBread implements IBread { // 準備材料public void prepair() { System.out.println("準備麵粉、水以及發酵粉..."); } // 和麵public void kneadFlour() { System.out.println("和麵..."); } // 蒸饅頭public void steamed() { System.out.println("蒸饅頭...香噴噴的饅頭出爐了!"); } /** * 加工饅頭方法*/ public void process() { // 準備材料prepair(); // 和麵kneadFlour(); // 蒸饅頭steamed(); }}3.3 創建抽象裝飾者――AbstractBread
package com.demo.decorator;import com.demo.abs.IBread;/** * 抽象裝飾者* * @author * */public abstract class AbstractBread implements IBread { // 存儲傳入的IBread對象private final IBread bread; public AbstractBread(IBread bread) { this.bread = bread; } // 準備材料public void prepair() { this.bread.prepair(); } // 和麵public void kneadFlour() { this.bread.kneadFlour(); } // 蒸饅頭public void steamed() { this.bread.steamed(); } // 加工饅頭方法public void process() { prepair(); kneadFlour(); steamed(); }}3.4 創建染色劑裝飾者――CornDecorator
package com.demo.decorator;import com.demo.abs.IBread;/** * 染色的玉米饅頭* * @author * */public class CornDecorator extends AbstractBread { // 構造方法public CornDecorator(IBread bread) { super(bread); } // 黑心商販開始染色了public void paint() { System.out.println("添加檸檬黃的著色劑..."); } // 重載父類的和麵方法@Override public void kneadFlour() { // 在麵粉中加入染色劑之後才開始和麵this.paint(); // 和麵super.kneadFlour(); }}3.5 創建甜蜜素裝飾者――SweetDecorator
package com.demo.decorator;import com.demo.abs.IBread;/** * 甜蜜素饅頭* * @author * */public class SweetDecorator extends AbstractBread { // 構造方法public SweetDecorator(IBread bread) { super(bread); } // 黑心商販開始添加甜蜜素public void paint() { System.out.println("添加甜蜜素..."); } // 重載父類的和麵方法@Override public void kneadFlour() { // 在麵粉中加入甜蜜素之後才開始和麵this.paint(); // 和麵super.kneadFlour(); }}3.6 生產甜玉米饅頭――Client
package com.demo;import com.demo.abs.IBread;import com.demo.abs.NormalBread;import com.demo.decorator.CornDecorator;import com.demo.decorator.SweetDecorator;/** * 客戶端應用程序* * @author * */public class Client { /** * @param args */ public static void main(String[] args) { // 生產裝飾饅頭System.out.println("/n====開始裝飾饅頭!!!"); // 創建普通的正常饅頭實例// 這是我們需要包裝(裝飾)的對象實例IBread normalBread = new NormalBread(); // 下面就開始對正常饅頭進行裝飾了! ! ! // 使用甜蜜素裝飾饅頭normalBread = new SweetDecorator(normalBread); // 使用檸檬黃的著色劑裝飾饅頭normalBread = new CornDecorator(normalBread); // 生產饅頭信息normalBread.process(); System.out.println("====裝飾饅頭結束!!!"); }}4. 運行結果
====開始裝飾饅頭! ! !
準備麵粉、水以及發酵粉...
添加檸檬黃的著色劑...
添加甜蜜素...
和麵...
蒸饅頭...香噴噴的饅頭出爐了!
====裝飾饅頭結束! ! !
三、該模式設計原則
1 封閉變化部分
2 “開一閉"原則
3 面向抽象編程
4 優先使用組合,而非繼承
四、使用場合
1. 當我們需要為某個現有對象動態增加一個新功能或職責時,可以考慮使用裝飾者模式。
2. 當某個對象的職責經常發生變化或經常需要動態增加職責,避免為了適應這樣的變化而增加繼承子類擴展的方式,因為這種方式會造成子類膨脹速度過快,難以控制,此時可以使用裝飾者模式。
五、裝飾者模式靜態類圖
更多關於java算法相關內容感興趣的讀者可查看本站專題:《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。