一、概念
裝飾者模式就是對現有類的功能進行擴展,相比繼承更加靈活一些。
二、例子
圖中ShapeDecorator爲裝飾者抽象類,裏面有成員shape(也可以寫到RedShapeDecorator中,圖中在ShapeDecorator和RedShapeDecorator中僅有一處存在shape即可,圖中兩處均有,個人覺得有誤)、接口的函數draw、以及構造函數來對成員Shape進行賦值。RedShapeDecorator通過繼承抽象裝飾類來對Shape子類的功能進行擴展,重寫了draw,以及在自己的構造函數中調用對Shape進行功能擴展的函數setRedBorder()函數。
具體代碼如下:
//基類接口
public interface Shape {
void draw();
}
//子類
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
//抽象裝飾類
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
//使用裝飾類對Shape子類的功能進行擴展
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
ShapeDecorator(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
//測試類
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
三、優缺點
優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實現類的功能。
缺點:多層裝飾比較複雜。
四、個人理解
裝飾者模式有點類似於上一節的適配器模式的擴展。適配器模式中有成員B,並通過繼承實現A的函數,在A的函數中調用B的函數。而抽象裝飾類是有成員A且繼承了類A,爲了能擴展各式各樣的功能,用了一個類C繼承抽象裝飾類,在C中,實現了類A的虛函數,且在虛函數中調用了成員A的虛函數並調用了C中寫的針對類A擴展的功能函數。其中的成員均是通過構造函數傳入類對象進行賦值(裝飾者模式類C的構造函數調用了抽象裝飾類的構造函數對成員A進行賦值)。
這樣看裝飾者模式有點類似於適配器模式的一個變形或者特例。