定義:裝飾設計模式允許向一個現有的物件添加功能,而不改變其結構(這就很符合程式設計的“開閉原則”),重點突出類功能的增強,屬于結構型創建模式,這種模式創建了一個裝飾類,用來包裝原有類,保持類方法簽名完整的情況下,提供了額外的功能,
意圖:動態地給一個物件增加一些額外的職責,裝飾是比子類更為靈活和優秀的一種方案;
主要解決:通常擴展一個類我們通常使用繼承實作,由于繼承為類引入特征,通常隨著功能的擴展,子類會很膨脹,容易造成類爆炸;裝飾設計模式是一種使用組合替代繼承的最佳實作,《effective java》中也建議“組合優先于繼承”,面向物件編程有封裝、繼承和多型三大特征,其中封裝和繼承卻有一點矛盾,繼承意味著子類依賴了父類的實作,一旦父類中改變了規則,會對子類造成影響,這是打破封裝的一種表現,而組合就是巧用封裝來實作繼承功能的代碼復用;
何時使用:在不想增加很多子類的情況下擴展類的功能;
設計模式結構圖:

模式角色分析:
1、抽象構件角色(Component):定義一個抽象介面,用來規范被裝飾類的行為;
2、具體構件角色(ConcreteComponent):需要被裝飾的目標物件;
3、抽象裝飾角色(decorator):持有一個具體構件物件的實體,并定義一個與抽象構建介面一致的介面;
4、具體裝飾角色(ConcreteDecorator):具體的裝飾類,負責給被裝飾者擴展功能;
優點:
1、裝飾和繼承都能達到擴展類功能的目的,但是裝飾模式更加靈活;
2、裝飾設計模式有很好的可擴展性;
3、通過使用不同的具體裝飾類,以及這些類的排列組合,可以實作多重裝飾;
缺點:
裝飾設計或是會導致程式設計中出現許多小物件,如果過度使用會使程式變得更加復雜;
UML類圖:

測驗代碼:
package cn.com.pep.model.decarator.impl2; /** * * @Title: Shape * @Description: 抽象構件角色(Component),用來約束被裝飾物件的行為 * @author wwh * @date 2022-9-1 16:11:29 */ public interface Shape { /** * * @Title: draw * @Description: */ public void draw(); }
package cn.com.pep.model.decarator.impl2; /** * * @Title: Circle * @Description: 具體構件角色(ConcreteComponent),被裝飾的物件 * @author wwh * @date 2022-9-1 16:14:50 */ public class Circle implements Shape { @Override public void draw() { System.err.println("Shape: Circle."); } }
package cn.com.pep.model.decarator.impl2; /** * * @Title: Rectangle 具體構件角色(ConcreteComponent),被裝飾的物件 * @Description: * @author wwh * @date 2022-9-1 16:13:36 */ public class Rectangle implements Shape { @Override public void draw() { System.err.println("Shape: Recatangle."); } }
package cn.com.pep.model.decarator.impl2; /** * * @Title: ShapeDecorator * @Description: 抽象裝飾角色(Decorator),定義一組與抽象構件角色相同的行為, * 通過實作介面來定義,并持有一個具體構件角色的參考,在完成裝飾設計模式增加的功能之后再呼叫原有功能 * @author wwh * @date 2022-9-1 16:16:42 */ public abstract class ShapeDecorator implements Shape{ private Shape shape; public ShapeDecorator(Shape shape) { this.shape = shape; } @Override public void draw() { shape.draw(); } }
package cn.com.pep.model.decarator.impl2; /** * * @Title: RedShapeDecorator * @Description: 具體的裝飾者類,負責給被裝飾者類擴展功能; * @author wwh * @date 2022-9-1 16:55:38 */ public class RedShapeDecorator extends ShapeDecorator{ public RedShapeDecorator(Shape shape) { super(shape); } @Override public void draw() { super.draw(); setRedColor(); } private void setRedColor() { System.err.println("Red Color!"); } }
package cn.com.pep.model.decarator.impl2; /** * * @Title: DecoratorPatternDemo * @Description: 測驗類 * @author wwh * @date 2022-9-1 16:56:54 */ public class DecoratorPatternDemo { public static void main(String[] args) { Shape shape = new Rectangle(); ShapeDecorator decorator = new RedShapeDecorator(shape); decorator.draw(); } }
裝飾設計模式在JDK原始碼中的應用:
裝飾設計模式在jdk原始碼中最具代表性的應用莫過于I/O體系中的InputStream/OutputStream,Reader/Writer等,現在我們就以InputStream為例進行分析:
抽象構件角色(Component):InputStream類,用來定義具體構件的行為;
具體構件角色(ConcreteComponent):FileInputStream、ByteArrayInputStream、ObjectInputStream類,具體被裝飾的類;
抽象裝飾角色(Decorator):FilterInputStream類,通過繼承抽象構建角色類來定義一組與具體構件類相同的行為,再通過聚合的方式來持有被裝飾角色的參考;
具體裝飾角色(ConcreteDecorator):BufferedInputStream、DataInputStream、CheckedInputStream類,具體裝飾者類,負責給被裝飾者增加功能;
寫在后面:
裝飾設計模式中,裝飾者和被裝飾者都可以獨立擴展,沒有耦合關系,被裝飾者無需知道裝飾者的存在,裝飾者也無需關心被裝飾者的具體細節,裝飾設計模式可以動態擴展一個類的功能,
是繼承的一種替代方案,但是裝飾的層級過多可能比較復雜,
本文來自博客園,作者:一只烤鴨朝北走,僅用于技術學習,所有資源都來源于網路,部分是轉發,部分是個人總結,歡迎共同學習和轉載,轉載請在醒目位置標明原文,如有侵權,請留言告知,及時撤除,轉載請注明原文鏈接:https://www.cnblogs.com/wha6239/p/16646861.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/503490.html
標籤:其他

