解決問題
它主要解決的問題是“遞迴、迴圈”問題或者大量的if-else 問題。通過定義不通的receiver,並在執行時決定receiver的執行順序。它帶來的一個好處是:receiver邏輯耦合(可以分不同的場景劃分receiver邏輯), 程式碼結構清晰。
應用場景
資訊或者請求 需要經過大量的if-else處理(轉換成由多個receiver中的其中一個進行處理);
資訊或請求 需要進行流水線處理(即需要經過層層加工)
原理圖(UML)
Handler:持有nextHander物件,以便交下一個鏈條;並持有一個handle方法來處理請求
Receiver:實現Handler介面,並實現具體的處理邏輯
Sender:生成具有一定處理順序的鏈條,並啟動鏈條的頭部來處理請求。
示例
這裡我們舉一個場景:去飯店吃飯,首先我們要向點餐員點菜、然後點餐員將菜名報給廚師、廚師做完菜之後將菜端到我們面前。
public abstract class Handler {
protected Handler nextHandler;
public abstract void handle();
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
}
public class OrderTaker extends Handler {
@Override
public void handle() {
System.out.println("請客人點餐");
System.out.println("客人點餐完成");
if (this.nextHandler != null) {
nextHandler.handle();
} else {
System.out.println("廚師下班了。。。");
}
}
}
public class Cooker extends Handler {
@Override
public void handle() {
System.out.println("為客人做菜");
System.out.println("做菜完成");
if (this.nextHandler != null) {
nextHandler.handle();
} else {
System.out.println("該招送餐員了。。。。");
}
}
}
public class Deliver extends Handler {
@Override
public void handle() {
System.out.println("將菜送到客人面前");
}
}
public class Manager {
public static void main(String[] args) {
// 組織結構
OrderTaker orderTaker = new OrderTaker();
Cooker cooker = new Cooker();
Deliver deliver = new Deliver();
orderTaker.setNextHandler(cooker);
cooker.setNextHandler(deliver);
// 來一個客人
orderTaker.handle();
}
}
複製程式碼
下面的這種形式是一個變種,但其在各種基本元件中應用則更為廣泛
spring -filter/interceptor都是採用的該模式,下面貼一部分OkHtpp中的對請求的處理原始碼。該示例參考:https://blog.csdn.net/yxhuang2008/article/details/72566928
public interface Interceptor {
Response intercept(Chain chain) throws IOException;
interface Chain{
Request request();
Response proceed(Request request) throws IOException;
}
}
public class BridgeInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request userRequest = chain.request();
Response networkResponse = chain.proceed(userRequest);
System.out.println("BridgeInterceptor intercept");
return networkResponse;
}
}
public class CacheInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
System.out.println("CacheInterceptor intercept");
return response;
}
}
public class ConnectInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = new Response();
System.out.println("ConnectInterceptor intercept");
return response;
}
}
public class RealInterceptorChain implements Interceptor.Chain{
private final List<Interceptor> interceptors;
private final int index;
private final Request request;
private int calls;
public RealInterceptorChain(List<Interceptor> interceptors, int index, Request request) {
this.interceptors = interceptors;
this.index = index;
this.request = request;
}
@Override
public Request request() {
return request;
}
@Override
public Response proceed(Request request) throws IOException {
if (index >= interceptors.size()) {
throw new AssertionError();
}
calls++;
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
if (index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn`t null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
return response;
}
}
public class TempClient {
public static void main(String[] args) throws IOException {
List<Interceptor> interceptors = new ArrayList<Interceptor>();
interceptors.add(new BridgeInterceptor());
interceptors.add(new CacheInterceptor());
interceptors.add(new ConnectInterceptor());
Request request = new Request();
Interceptor.Chain chain = new RealInterceptorChain(interceptors, 0, request);
chain.proceed(request);
/**
* 執行結果, 倒序
* ConnectInterceptor intercept
* CacheInterceptor intercept
* BridgeInterceptor intercept
*/
}
}
複製程式碼