責任鏈(Chain of Resposibility) 模式
概念
責任鏈(chain of Resposibility) 模式:為了避免請求發送者與多個請求處理者耦合在一起,于是將所有請求的處理者 通過前一對象記住其下一個對象的引用而連成一條鏈
;當有請求發生時,可將請求沿著這條鏈傳遞,直到有對象處理它位置。屬于對象行為型模式。
-
抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。
-
具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將請求轉給他的后繼者。
-
客戶類(Client)角色:創建處理鏈,并向鏈頭的具體處理者對象提交請求,他不關心處理細節和請求的傳遞過程。
代碼
需求1:a1 -> a2 -> a3
實現先a1處理完交給a2,a2處理完再交給a3的邏輯,即: a1 -> a2 -> a3
public class Teacher {private String name;public Teacher(String name) {this.name = name;}// 下一個處理的老師;1、鏈條的引用點private Teacher next;public Teacher getNext() {return next;}public void setNext(Teacher next) {this.next = next;}void handlerRequest() {System.out.println(this + "正在處理。。。。。。。。");// 2、下一個繼續if (next != null) {next.handlerRequest();}}@Overridepublic String toString() {return "Teacher{" +"name='" + name + '\'' +'}';}
}
public class MainTest {public static void main(String[] args) {Teacher a1 = new Teacher("a1");Teacher a2 = new Teacher("a2");Teacher a3 = new Teacher("a3");// 3、構造鏈條// a1->a2->a2a1.setNext(a2);a2.setNext(a3);a1.handlerRequest();}
}
測試結果:
Teacher{name='a1'}正在處理。。。。。。。。
Teacher{name='a2'}正在處理。。。。。。。。
Teacher{name='a3'}正在處理。。。。。。。。
需求2:1->2->3->本人->3->2->1
這個也就是我們學習過的Filter了
代碼實現:
① Filter 接口
public interface Filter {void doFilter(Request request,Response response,FilterChain chain);
}
@Data
public class Request {// 請求內容String msg;public Request(String msg) {this.msg = msg;}
}
@Data
public class Response {// 響應內容private String content;public Response(String content) {this.content = content;}
}
② Filter 的三個實現類
public class HttpFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 第一個filter的功能request.msg += ">>>";System.out.println("HttpFilter ... doFilter之前");// 放行chain.doFilter(request, response, chain);System.out.println("HttpFilter ... doFilter之后");}
}
public class CharacterFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 功能request.msg += "====";System.out.println("CharacterFilter ... doFilter之前");// 放行chain.doFilter(request, response, chain);System.out.println("CharacterFilter ... doFilter之后");}
}
public class EncodingFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 功能request.msg += "oooo";System.out.println("EncodingFilter ... doFilter之前");// 放行chain.doFilter(request, response, chain);System.out.println("EncodingFilter ... doFilter之后");}
}
③ 我們的目標方法
public class My {void hello() {System.out.println("調用my.hello()方法");}
}```④ 維護鏈條```java
/*** 靠他維護鏈條* handlerExecutionChain** @author zhuicat* @since 2023/8/13 8:19*/
public class FilterChain implements Filter {// 游標:記錄當前執行的步驟int cursor;// Filter 的鏈List<Filter> filterChain = new ArrayList<>();// 最終要執行的目標方法My target;// 添加 filter 方法void addFilter(Filter filter) {filterChain.add(filter);}@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {// 執行第一個 filter ,一次往下// 游標小于總數量filter一直往下獲取執行if (cursor < filterChain.size()) {Filter filter = filterChain.get(cursor);cursor++;// 執行 filterfilter.doFilter(request, response, chain);} else {// filter執行完了,需要執行目標方法了target.hello();}}public My getTarget() {return target;}public void setTarget(My target) {this.target = target;}
}
⑤ 主方法
public class MainTest {public static void main(String[] args) {FilterChain chain = new FilterChain();// web.xmlHttpFilter httpFilter = new HttpFilter();CharacterFilter characterFilter = new CharacterFilter();EncodingFilter encodingFilter = new EncodingFilter();chain.addFilter(httpFilter);chain.addFilter(characterFilter);chain.addFilter(encodingFilter);chain.setTarget(new My());// filter 如何鏈式執行chain.doFilter(new Request("hello,world"), new Response("dddddddddddddddddd"), chain);}
}
⑥ 執行結果
HttpFilter ... doFilter之前
CharacterFilter ... doFilter之前
EncodingFilter ... doFilter之前
調用my.hello()方法
EncodingFilter ... doFilter之后
CharacterFilter ... doFilter之后
HttpFilter ... doFilter之后
完成上述需求