裝飾器(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 裝飾器模式結構
裝飾器主要使用組合關係來建立一個裝飾物件,用於包裹真實物件,並在保持真實物件的類結構不變的前提下為其提供額外的功能。具體的基本結構如下所示:
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中有很多裝飾器的應用:
如上圖所示,比如InputStream
後面的若干裝飾器類都是對其的功能擴充套件。
2.2 MyBatis 中 Cache的應用
Cache 中除了有資料儲存和快取的基本功能外還有其他附加的 Cache 類,比如有 FifoCache(先進先出)、LruCache(最近最少使用LRU)、SychronizedCache(防止多執行緒併發訪問)的眾多附加功能的快取類。都是裝飾器的應用: