職責鏈模式(Chain of Responsibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。ide
適用場景:性能
一、有多個的對象能夠處理一個請求,哪一個對象處理該請求運行時刻自動肯定;測試
二、在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求;this
三、處理一個請求的對象集合應被動態指定。spa
通用類圖:代理
在大學裏面當班幹部,時常要向上級申請各方面的東西。譬如申請全班外出秋遊,普通同窗將申請表交給班長,班長簽字以後交給輔導員,輔導員批准以後上交到主任辦公室…就是這樣,一個請求(這裏是一份申請表)有時候須要通過好幾個級別的處理者(這裏是輔導員、主任)的審查纔可以最終被肯定可行與否。對象
在這裏表現出來的是一個職責鏈,即不一樣的處理者對同一個請求可能擔負着不一樣的處理方式、權限,可是咱們但願這個請求必須到達最終拍板的處理者(不然秋遊就沒戲了)。這種關係就很適合使用職責鏈模式了。blog
代碼實現以下:接口
- // 全局變量,接口類型
- /**
- * 使用Java中的interface定義全局變量,可根據具體須要在
- * 具體的包中使用靜態導入相關的全局變量,語法以下:
- * import static package01.package02.*;
- */
- interface Levels {
- public static final int LEVEL_01 = 1;
- public static final int LEVEL_02 = 2;
- public static final int LEVEL_03 = 3;
- }
- // 抽象請求類
- abstract class AbstractRequest {
- private String content = null;
- public AbstractRequest(String content) {
- this.content = content;
- }
- public String getContent() {
- return this.content;
- }
- // 得到請求的級別
- public abstract int getRequestLevel();
- }
- // 具體請求類01
- class Request01 extends AbstractRequest {
- public Request01(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_01;
- }
- }
- // 具體請求類02
- class Request02 extends AbstractRequest {
- public Request02(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_02;
- }
- }
- // 具體請求類03
- class Request03 extends AbstractRequest {
- public Request03(String content) {
- super(content);
- }
- @Override
- public int getRequestLevel() {
- return Levels.LEVEL_03;
- }
- }
- // 抽象處理者類,
- abstract class AbstractHandler {
- // 責任鏈的下一個節點,即處理者
- private AbstractHandler nextHandler = null;
- // 捕獲具體請求並進行處理,或是將請求傳遞到責任鏈的下一級別
- public final void handleRequest(AbstractRequest request) {
- // 若該請求與當前處理者的級別層次相對應,則由本身進行處理
- if (this.getHandlerLevel() == request.getRequestLevel()) {
- this.handle(request);
- } else {
- // 當前處理者不能勝任,則傳遞至職責鏈的下一節點
- if (this.nextHandler != null) {
- System.out.println("當前 處理者-0" + this.getHandlerLevel()
- + " 不足以處理 請求-0" + request.getRequestLevel());
- // 這裏使用了遞歸調用
- this.nextHandler.handleRequest(request);
- } else {
- System.out.println("職責鏈上的全部處理者都不能勝任該請求...");
- }
- }
- }
- // 設置責任鏈中的下一個處理者
- public void setNextHandler(AbstractHandler nextHandler) {
- this.nextHandler = nextHandler;
- }
- // 獲取當前處理者的級別
- protected abstract int getHandlerLevel();
- // 定義鏈中每一個處理者具體的處理方式
- protected abstract void handle(AbstractRequest request);
- }
- // 具體處理者-01
- class Handler01 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_01;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-01 處理 " + request.getContent() + "\n");
- }
- }
- // 具體處理者-02
- class Handler02 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_02;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-02 處理 " + request.getContent()+ "\n");
- }
- }
- // 具體處理者-03
- class Handler03 extends AbstractHandler {
- @Override
- protected int getHandlerLevel() {
- return Levels.LEVEL_03;
- }
- @Override
- protected void handle(AbstractRequest request) {
- System.out.println("處理者-03 處理 " + request.getContent()+ "\n");
- }
- }
- // 測試類
- public class Client {
- public static void main(String[] args) {
- // 建立指責鏈的全部節點
- AbstractHandler handler01 = new Handler01();
- AbstractHandler handler02 = new Handler02();
- AbstractHandler handler03 = new Handler03();
- // 進行鏈的組裝,即頭尾相連,一層套一層
- handler01.setNextHandler(handler02);
- handler02.setNextHandler(handler03);
- // 建立請求並提交到指責鏈中進行處理
- AbstractRequest request01 = new Request01("請求-01");
- AbstractRequest request02 = new Request02("請求-02");
- AbstractRequest request03 = new Request03("請求-03");
- // 每次提交都是從鏈頭開始遍歷
- handler01.handleRequest(request01);
- handler01.handleRequest(request02);
- handler01.handleRequest(request03);
- }
- }
測試結果:
- 處理者-01 處理 請求-01
- 當前 處理者-01 不足以處理 請求-02
- 處理者-02 處理 請求-02
- 當前 處理者-01 不足以處理 請求-03
- 當前 處理者-02 不足以處理 請求-03
- 處理者-03 處理 請求-03
一、對於每個請求都須要遍歷職責鏈,性能是個問題;
二、抽象處理者 AbstractHandler 類中的 handleRequest() 方法中使用了遞歸,棧空間的大小也是個問題。
我的見解:
職責鏈模式對於請求的處理是不知道最終處理者是誰,因此是運行動態尋找並指定;而命令模式中對於命令的處理時在建立命令是已經顯式或隱式綁定了接收者。
相關文章:
命令模式(Command)的兩種不一樣實現(http://haolloyin.blog.51cto.com/1177454/339076)
(Template Method)模板方法模式的Java實現(http://haolloyin.blog.51cto.com/1177454/333063)
裝飾模式(Decorator)與動態代理的強強聯合(http://haolloyin.blog.51cto.com/1177454/338671)