設計模式-裝飾器模式
裝飾器模式所解決的問題是,在不改變原來方法代碼的情況下對方法進行修飾,從而豐富方法功能。
Spring架構中的裝飾器模式
在Spring架構中,以線程池進行舉例。
線程池
線程池是一個對線程集中管理的對象,集中管理線程的創建和銷毀以及調度。線程池中的線程所要執行的,就是傳入線程池的任務,線程池安排線程對任務進行執行。
任務就是編碼者想要交給線程池來執行的代碼塊,如果編碼者想要給任務加上一些修飾,線程池便提供了修飾類入口。編碼者可以在任務執行前后進行日志打印,線程變量設置或釋放。
一般線程池配置
import com.config.decorator.ThreadTaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;@Configuration
public class ThreadPoolConfig {@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(100);executor.setQueueCapacity(100);executor.setKeepAliveSeconds(60);executor.setTaskDecorator(new ThreadTaskDecorator());executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return executor;}
}
線程裝飾器
類ThreadTaskDecorator實現了接口TaskDecorator的decorate方法,對原任務進行了裝飾。
import org.springframework.core.task.TaskDecorator;public class ThreadTaskDecorator implements TaskDecorator {@Overridepublic Runnable decorate(Runnable runnable) {return () -> {//前置try {//前置runnable.run();//原任務}finally {//后置}//后置};}
}
線程池初始化–裝飾器模式體現
初始化代碼來自類ThreadPoolTaskExecutor.class,對無關代碼進行了折疊。
protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {...ThreadPoolExecutor executor = new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler) {public void execute(Runnable command) {Runnable decorated = command;if (ThreadPoolTaskExecutor.this.taskDecorator != null) {decorated = ThreadPoolTaskExecutor.this.taskDecorator.decorate(command);if (decorated != command) {ThreadPoolTaskExecutor.this.decoratedTaskMap.put(decorated, command);}}super.execute(decorated);}...};...return executor;}
從初始化代碼中可以看見,在創建executor時對ThreadPoolExecutor的父類接口Executor中的execute方法進行了實現,其中就是判斷任務裝飾器taskDecorator不為空的情況下,調用taskDecorator對象的decorate方法對command即原任務進行裝飾。這里的taskDecorator對象就是我們前面通過nre ThreadTaskDecorator()
傳遞進去的,在線程池初始化的時候被調用到decorate,對原任務進行裝飾。
裝飾器模式是將裝飾和被裝飾者進行分離,裝飾和被裝飾者相互獨立。這種分離的方式使得,一種裝飾只需要實現一次,便可以重復使用。這是代碼復用的很好方案。