裝飾者模式屬於結構型模式,允許在不修改原類別、不使用繼承的前提下,動態為物件新增職責。它以組合取代繼承,避免「類別爆炸」,符合開放封閉原則。
Shape。Circle、Rectangle。RedShapeDecorator 加紅框。
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; }
@Override public void draw() { decoratedShape.draw(); } // 預設轉發
}
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) { super(decoratedShape); }
@Override public void draw() {
decoratedShape.draw(); // 1. 執行原本繪製
setRedBorder(decoratedShape); // 2. 新增裝飾行為
}
private void setRedBorder(Shape s) { System.out.println("Border Color: Red"); }
}
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape 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();
}
}
Circle with normal border Shape: Circle Circle of red border Shape: Circle Border Color: Red Rectangle of red border Shape: Rectangle Border Color: Red
new RedShapeDecorator(new BlueShapeDecorator(new Circle())) 疊加多種效果。Function<T,T> 組合實現輕量裝飾,如 Stream 管線。BufferedInputStream、GZIPInputStream 皆為經典裝飾者實作。| 優點 | 缺點 |
|---|---|
| 執行期動態組合功能,避免靜態繼承爆炸 | 產生大量細小物件,除錯較難追蹤 |
| 單一職責,每個裝飾者只關心特定邏輯 | 過度使用導致程式碼碎片化,增加理解成本 |
| 符合開放封閉原則,新增裝飾不修改既有代碼 | 型別檢查變複雜(instanceof 判斷特定裝飾) |
裝飾者模式是「付費增加功能」的經典實踐。掌握其「組合 > 繼承」的設計哲學,能讓你在需要動態擴展物件行為時,寫出優雅且可維護的代碼。