Java實現23種設計模式(六):責任鏈模式(重點掌握)

二十三種設計模式分類

設計模式三大分類.jpg


一、概述

責任鏈(Chain of Responsibility)模式的定義:爲了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿着這條鏈傳遞,直到有對象處理它爲止。

在責任鏈模式中,客戶只需要將請求發送到責任鏈上即可,無須關心請求的處理細節和請求的傳遞過程,所以責任鏈將請求的發送者和請求的處理者解耦了。

優點

  • 降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。
  • 增強了系統的可擴展性。可以根據需要增加新的請求處理類,滿足開閉原則。
  • 增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。
  • 責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其後繼者的引用,不需保持其他所有處理者的引用,這避免了使用衆多的if 或者 if···else 語句。
  • 責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任範圍,符合類的單一職責原則。

缺點

  • 不能保證每個請求一定被處理。由於一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
  • 對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。
  • 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的複雜性,可能會由於職責鏈的錯誤設置而導致系統出錯,如可能會造成循環調用。

場景

1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
3、可動態指定一組對象處理請求。


二、實現

1. 結構圖

職責鏈模式主要包含以下角色:

  • 抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個後繼連接。
  • 具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的後繼者。
  • 客戶類(Client)角色:創建處理鏈,並向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。
    責任鏈模式

PS:UML結構圖可以參考,例子實現並不根據UML圖來完成,靈活實現即可;

2. 實現

  • 多個過濾器
package cn.missbe.model.responsibilityChain.filter;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 * @author lyg  2020/4/27 下午7:21
 * description:
 * 責任鏈模式:具體的Filter
 **/

public interface Filter {
    boolean doFilter(Message msg);
}
/**笑臉過濾器*/
public class FaceFilter implements Filter {
    @Override
    public boolean doFilter(Message msg) {
        msg.setMsg(msg.getMsg().replace(":(", "^_^"));
        return true;
    }
}
/**Html字符過濾器*/
public class HtmlFilter implements  Filter {
    @Override
    public boolean doFilter(Message msg) {
        msg.setMsg(msg.getMsg().replaceAll("<","["));
        msg.setMsg(msg.getMsg().replaceAll(">","]"));
        return true;
    }
}
/**敏感詞過濾器*/
public class SensitiveFilter implements Filter {
    @Override
    public boolean doFilter(Message msg) {
        if (msg.getMsg().contains("996")) {
            return false;
        }
        return true;
    }
}
  • 過濾器責任鏈
package cn.missbe.model.responsibilityChain.filter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 * @author lyg  2020/4/27 下午7:33
 * description:
 * 過濾器鏈
 **/

public class FilterChain {
    private List<Filter> filterChain = new ArrayList<>();

    public FilterChain registerFilter(Filter filter) {
        filterChain.add(filter);
        return this;
    }

    public boolean doFilter(Message msg){
        for (Filter filter : filterChain) {
            if (!filter.doFilter(msg)) {
                return false;
            }
        }
        return true;
    }
}
  • Main主類
package cn.missbe.model.responsibilityChain.filter;

/**
 * Copyright (c) 2020.
 * Email: [email protected]
 * @author lyg  2020/4/27 下午7:30
 * description:
 * 責任鏈模式
 **/

public class Main {
    public static void main(String[] args) {
        Message message = new Message();
        message.setMsg("過濾器測試,<script>笑臉:(,這是一個敏感詞996.</script>");
        FilterChain filterChain = new FilterChain();
        filterChain.registerFilter(new HtmlFilter()).registerFilter(new FaceFilter()).registerFilter(new SensitiveFilter());
        filterChain.doFilter(message);
        System.out.println(message);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章