設計模式學習筆記(十)裝飾器模式及其應用

歸斯君發表於2022-03-31

裝飾器(Decorator)模式:指不改變現有物件結構的情況下,動態地給該物件增加額外功能。

一、裝飾器模式介紹

裝飾器模式允許向一個現有的物件新增新的功能,同時不改變其結果。比如Java 中的IO框架中,FileInputStream(處理檔案)、ByteArrayInputStream(處理位元組陣列)、BufferedInputStream(帶快取的處理類)等就是對InputStream進行的功能擴充套件,這就是裝飾器模式的典型應用。比如下面就是以快取方式讀取輸入流:

InputStream inputStream = new BufferedInputStream(new FileInputStream("test.txt"));
byte[] data = new byte[128];
while(inputStream.read(data) != -1){
    //...
} 

1.1 裝飾器模式結構

裝飾器主要使用組合關係來建立一個裝飾物件,用於包裹真實物件,並在保持真實物件的類結構不變的前提下為其提供額外的功能。具體的基本結構如下所示:

image-20220331203832443

  • Component:抽象構件,定義一個抽象介面以規範準備接收附加責任的物件
  • ComponentA:具體構件,實現抽象構件,通過裝飾角色為其新增一些職責
  • Decorator:抽象裝飾構件,幷包含具體構件的例項
  • DecoratorA、DecoratorB:實現抽象裝飾構件的具體裝飾構件,包含實現抽象裝飾的相關方法
  • Client:客戶端

1.2 裝飾器模式實現

根據上面的類圖可以實現如下程式碼:

/**
 * @description: 抽象構件角色
 * @author: wjw
 * @date: 2022/3/31
 */
public interface Component {

    public void operation();
}

/**
 * @description:具體構件角色
 * @author: wjw
 * @date: 2022/3/31
 */
public class ComponentA implements Component{

    public ComponentA() {
        System.out.println("建立具體構件componentA");
    }

    @Override
    public void operation() {
        System.out.println("我是具體構件A的operation方法");
    }
}

/**
 * @description: 抽象裝飾
 * @author: wjw
 * @date: 2022/3/31
 */
public class Decorator implements Component{

    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

/**
 * @description: 具體裝飾角色A
 * @author: wjw
 * @date: 2022/3/31
 */
public class DecoratorA extends Decorator{

    public DecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addedFunction();
    }

    /**
     * 增加的額外功能
     */
    public void addedFunction() {
        System.out.println("我是為具體裝飾角色A增加額外功能方法addedFunction");
    }
}

/**
 * @description: 具體裝飾角色B
 * @author: wjw
 * @date: 2022/3/31
 */
public class DecoratorB extends Decorator{

    public DecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addedFunction();
    }

    private void addedFunction() {
        System.out.println("為具體裝飾角色增加額外的功能B");
    }
}

/**
 * @description: 客戶端
 * @author: wjw
 * @date: 2022/3/31
 */
public class DecoratiorClient {

    public static void main(String[] args) {
        Component componentA = new ComponentA();
        componentA.operation();
        Decorator decoratorA = new DecoratorA(componentA);
        decoratorA.operation();
    }
}

二、裝飾器模式應用場景

2.1 Java IO 類中的應用

在開始介紹中提到,IO中有很多裝飾器的應用:

IO

如上圖所示,比如InputStream後面的若干裝飾器類都是對其的功能擴充套件。

2.2 MyBatis 中 Cache的應用

Cache 中除了有資料儲存和快取的基本功能外還有其他附加的 Cache 類,比如有 FifoCache(先進先出)、LruCache(最近最少使用LRU)、SychronizedCache(防止多執行緒併發訪問)的眾多附加功能的快取類。都是裝飾器的應用:

image-20220331224248502

參考資料

https://mp.weixin.qq.com/s/hDJs6iG_YPww7yeiPxmZLw?

http://c.biancheng.net/view/1366.html

相關文章