Design Pattern

Chapter 8 裝飾模式(Decorator Pattern)

定義

動態地將責任加諸於物件上,就增加功能來說,裝飾模式比產生子類別更為靈活。

組成

  1. 抽象物件(Component):定義了對象的接口,可以給這些對象動態增加職責(方法)。
  2. 具體物件(ConcreteComponent):定義了具體的構件對象,實現了在抽象構件中聲明的方法,裝飾器可以給它增加額外的職責(方法)。
  3. 抽象裝飾物件(Decorator):抽象構件類的子類,用於給具體構件增加職責,但是具體職責在其子類中實現。
  4. 具體裝飾物件(ConcreteDecorator):抽象裝飾類的子類,負責向構件添加新的職責。

程式碼

Step1

public interface Shape {
    public void draw();
}

Step2

public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("Shape:圓形");
    }
}


public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("Shape:方形");        
    }
}

Step3

public abstract class ShapeDecorator implements Shape{
    protected Shape decoratedShape;
    public ShapeDecorator(Shape decoratedShape){
       this.decoratedShape = decoratedShape;
    }
    @Override
    public void draw() {
        decoratedShape.draw();
    }
}

Step4

public class RedShapeDecorator extends ShapeDecorator{
    public RedShapeDecorator(Shape decoratedShape) {
       super(decoratedShape);        
    }

    @Override
    public void draw() {
       decoratedShape.draw();           
       setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape){
       System.out.println("Border Color: 紅色");
    }
}

Step5

public class DecoratorPatternDemo {
    public static void main(String[] args) {
       Shape circle = new Circle();
       Shape redCircle = new RedShapeDecorator(new Circle());
       Shape redSquare = new RedShapeDecorator(new Square());
       System.out.println("Circle with normal border");
       circle.draw();
       System.out.println("\nCircle of red border");
       redCircle.draw();
       System.out.println("\Square of red border");
       redSquare.draw();
    }
}

Step6(Output)

Circle with normal border
Shape:圓形

Circle of red border
Shape:圓形
Border Color: 紅色

Square of red border
Shape:方形
Border Color: 紅色

優點

  1. 提供比繼承更多的靈活性。
  2. 使用不同的具體物件,及裝飾物件的排列組合,可以創造出許多不同的行為組合。

缺點

  1. 進行系統設計的時候會產生很多小對象。
  2. 靈活的特性,也代表比繼承容易出錯,除錯也比較困難。