Java常用设计模式————装饰者模式
引言
裝飾者模式,又叫裝飾器模式。它可以動態(tài)的將新功能附加到對象上。在對象功能擴展方面,它比繼承更靈活,同時裝飾者模式也體現(xiàn)了OCP原則。
在客戶端調(diào)用使用了裝飾者模式的對象時,就好像在使用構(gòu)造器層層包裹核心對象,層層裝飾核心對象,因此叫做裝飾者模式。
一、裝飾者模式類圖
裝飾者模式屬于結(jié)構(gòu)型設(shè)計模式。在JDK的IO流API中,就利用了裝飾者模式:
以簡單的形狀和顏色為例。如何為不同的形狀裝飾新的顏色呢?
上圖中,Shape和ShapeDecorator都是抽象類,一般情況下,裝飾者模式中的頂層裝飾器類(ShapeDecorator)一定要是抽象類,因為它需要維護被裝飾者,并重寫特定行為。客戶端在調(diào)用的時候,并不會直接使用它,而是會使用具體的裝飾器類(Red、White)。
Shape類在本例中是一個抽象類,實際上也可以是一個接口,主要看有沒有需要維護的屬性。接口中是不允許有屬性的,所以如果需要維護一些公共屬性,那么可以采用抽象類,而如果只是封裝了行為,那么建議采用接口。
裝飾者模式的精髓在于,裝飾者模式將繼承和組合兩種技巧相結(jié)合。
繼承的目的是為了可以在原來的位置上取代被裝飾對象(前提是調(diào)用方使用的是父類引用)。
組合(采用構(gòu)造器傳入一個被裝飾對象,并在內(nèi)部維護這個對象屬性)的目的是可以在核心對象的基礎(chǔ)之上加以裝飾,即保留原來的核心對象的特征和行為,只做擴展,不做修改(OCP原則)。?
裝飾器子類在重寫被裝飾者的特定行為時,一定要注意,根據(jù)業(yè)務(wù)是否需要嚴(yán)格遵守對原來對象行為的擴展,而不是修改。如果是只擴展不修改,那么一定要在抽象裝飾器類中調(diào)用被裝飾對象的方法,并在裝飾器子類的方法中使用“super.”的形式間接調(diào)用被裝飾者的方法,然后根據(jù)裝飾需要,在調(diào)用的前后執(zhí)行裝飾邏輯。如果業(yè)務(wù)設(shè)計上允許對原有行為作出一些修改,那么其實并沒有嚴(yán)格遵守OCP原則,這種情況下,抽象裝飾器類的對原對象方法的調(diào)用可以視情況而定修改甚至忽略。后者違背OCP原則的方式不建議使用裝飾者模式來完成。
二、裝飾者模式代碼實現(xiàn)
/*** 圖形接口*/ public abstract class Shape {protected String name;public abstract void draw();public String getName() {return name;} } public class Circle extends Shape {public Circle() {name = "圓形";}@Overridepublic void draw() {System.out.println(name);} } public class Square extends Shape {public Square() {name = "正方形";}@Overridepublic void draw() {System.out.println(name);} } /*** 裝飾器抽象類*/ public abstract class ShapeDecorator extends Shape {protected Shape decoratedShape;public ShapeDecorator(Shape shape) {this.decoratedShape = shape;}@Overridepublic void draw() {decoratedShape.draw();} } public class Red extends ShapeDecorator {public Red(Shape shape) {super(shape);}@Overridepublic void draw() {paint();}// 隨意增加想要裝飾在核心對象上的功能private void paint() {System.out.println("紅色的" + decoratedShape.getName());} } public class White extends ShapeDecorator {public White(Shape shape) {super(shape);}@Overridepublic void draw() {paint();}private void paint() {System.out.println("白色的" + decoratedShape.getName());} }測試代碼:
public class Client {public static void main(String[] args) {Shape redCircle = new Red(new Circle());redCircle.draw();Shape whiteCircle = new White(new Circle());whiteCircle.draw();Shape redSquare = new Red(new Square());redSquare.draw();Shape whiteSquare = new White(new Square());whiteSquare.draw();} }測試結(jié)果:
紅色的圓形 白色的圓形 紅色的正方形 白色的正方形總結(jié)
裝飾者模式主要用于對現(xiàn)有對象添加新的功能,可在一定程度上代替繼承關(guān)系,實現(xiàn)低耦合關(guān)系。與橋接模式類似,都是為了防止類的膨脹而引出的結(jié)構(gòu)型設(shè)計模式。而且在思路上,與橋接模式呈現(xiàn)相反的類的依賴關(guān)系。
裝飾者模式基于OCP原則,不改變原來對象的屬性及行為,只做擴展。
它的類結(jié)構(gòu)特點有兩個:繼承和組合。
其中:
繼承的目的是為了可以在原來的位置上替代被裝飾對象(前提是調(diào)用方使用的是父類引用)。
組合(采用構(gòu)造器傳入一個被裝飾對象,并在內(nèi)部維護這個對象屬性)的目的是可以在核心對象的基礎(chǔ)之上加以裝飾,即保留原來的核心對象的特征和行為,只做擴展,不做修改(OCP原則)。
除了更好的實現(xiàn)對象功能的擴展和特性組合,但是如果擴展功能較多,被迫多層裝飾,就會使代碼變得較為復(fù)雜。
?
總結(jié)
以上是生活随笔為你收集整理的Java常用设计模式————装饰者模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基本农田卫星地图查询_发现谷歌地图替代网
- 下一篇: java美元兑换,(Java实现) 美元