一起來學習設計模式:裝飾器模式

weixin_34321977發表於2018-10-22

1.裝飾器模式的概念

裝飾器模式(Decorator Pattern)允許像一個顯示有的物件新增新功能,同時又不改變其結構;是對現有類的一個包裝
建立一個裝飾類,來包裝原有的類,比如說汽車已經有行駛的功能了,我想錦上添花,在車上加個音響,這樣是不是帥呆了。

  • 作用:動態地給一個物件增加新的功能
  • 要解決的問題:其實看到新增功能這幾個字,我們應該想到JAVA中的三大特性中的繼承,也可以實現類似的功能,那麼為什麼還要用裝飾器模式呢。這是因為隨著我們的系統的擴充套件,如果我們不斷繼承的話,子類會越來越多,難以管理
  • 如何實現:
    1、Component 類充當抽象角色,不應該具體實現。
    2、修飾類引用和繼承 Component 類,具體擴充套件類重寫父類方法。
    優點:解耦合,不會影響原本的類,是繼承的一個替代模式
    缺點:如果功能過多,多層裝飾會很麻煩

2.實現

2909474-f91a676fec6ec5d3.png
image.png

step1:

我們還是按圖上說的先定義一個Shape介面,和兩個實現類;

public interface Shape {
    void draw();
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("This is rectangle");
    }
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("This is Circle");
    }
}

step2:

裝飾器類

public abstract class ShapeDecorator implements Shape{
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    public void draw(){
        decoratedShape.draw();
    }
}

step3:

這裡我們就要擴充套件新的功能了

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: Red");
    }
}

step4:

測試程式

public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape readCircle = new RedShapeDecorator(new Circle());
        System.out.println("Circle with normal border");
        circle.draw();
        System.out.println("Circle of red border");
        readCircle.draw();
    }
}
2909474-98bec174b8ff3b4e.png
image.png

3.總結:

其實我們從上面一個簡簡單單的例項來看,貌似和繼承也沒多少差別。而且從程式碼理解上來看,直接繼承省心省力多了。但是,我們想想,如果我們的系統越來越大了,要繼承的類越來越多,那麼我們的.java檔案也會越來越多,也許某天你要改功能了就要滿世界找,這很影響效率,而如果我們集中在一個裝飾類裡面管理的話,那將會非常簡單,想加啥,減啥,都非常簡單,畢竟你全部東西都寫在那了,不用看滿天的子類了。
比較經典的裝飾器的應用我們可以看看JAVA 的IO的原始碼~
參考:
http://www.runoob.com/design-pattern/decorator-pattern.html

相關文章