Java設(shè)計模式之責(zé)任鏈模式
設(shè)計者往往會用攔截器去代替動態(tài)代理,然后將攔截器的接口提供給開發(fā)者,從而簡化開發(fā)者的開發(fā)難度,但是攔截器可能有多個。舉個例子,一個程序員需要請假一周,如果把請假申請單看成一個對象,那么它需要經(jīng)過項(xiàng)目經(jīng)理、部門經(jīng)理、人事等多個角色的審批,每個角色都有機(jī)會通過攔截這個申請單進(jìn)行審批或者修改。這事就要考慮提供項(xiàng)目經(jīng)理、部門經(jīng)理和人事的處理邏輯,所以需要提供3個攔截器,二傳遞的則是請假申請單。
當(dāng)一個對象在一條鏈上被多個攔截器處理(攔截器也可以選擇不攔截處理它)時,我們把這樣的設(shè)計模式成為責(zé)任鏈模式,它用于一個對象在多個角色中傳遞的場景。還是剛才的例子,申請單走到項(xiàng)目經(jīng)理,經(jīng)理可能把申請時間“一周”改為“5天”,從而影響了后面的審批,后面的審批都要根據(jù)前面的結(jié)果進(jìn)行。這個時候可以考慮用層層代理來實(shí)現(xiàn),就是當(dāng)申請單(target)走到項(xiàng)目經(jīng)理處,使用第一個動態(tài)代理proxy1,。當(dāng)它走到部門經(jīng)理處,部門經(jīng)理會得到一個在項(xiàng)目經(jīng)理的代理proxy1基礎(chǔ)上生成的proxy2來處理部門經(jīng)理的邏輯。當(dāng)它走到人事處,會在proxy2的基礎(chǔ)上生成proxy3.如果還有其他角色,依次類推即可,可用下圖來描述攔截邏輯:

我們定義下面的攔截器接口:
/**
* @Auther: haozz
* @Date: 2018/5/27 22:15
* @Description:攔截器接口
**/
public interface Interceptor {
boolean before(Object proxy, Object target, Method method,Object[] args);
void around(Object proxy,Object target,Method method,Object[] args);
void after(Object proxy,Object target,Method method,Object[] args);
}
再定義3個攔截器:
/**
* @Auther: haozz
* @Date: 2018/5/27 22:19
* @Description:攔截器1
**/
public class Interceptor1 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器1]的before方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器1]的after方法");
}
}
/**
* @Auther: haozz
* @Date: 2018/5/27 22:19
* @Description:攔截器2
**/
public class Interceptor2 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器2]的before方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器2]的after方法");
}
}
/**
* @Auther: haozz
* @Date: 2018/5/27 22:19
* @Description:攔截器3
**/
public class Interceptor3 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器3]的before方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.print("[攔截器3]的after方法");
}
}
我們使用上一篇(Java動態(tài)代理之?dāng)r截器的應(yīng)用)中用到的InterceptorJdkProxy類,測試一下這段代碼。如下:
@Test
public void MyTest(){
HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"com.csdn.blog.impl.Interceptor1");
HelloWorld proxy2 = (HelloWorld) InterceptorJdkProxy.bind(proxy1,"com.csdn.blog.impl.Interceptor2");
HelloWorld proxy3 = (HelloWorld) InterceptorJdkProxy.bind(proxy2,"com.csdn.blog.impl.Interceptor3");
proxy3.sayHelloWorld();
}
運(yùn)行這段diamante后得到這樣的結(jié)果,請注意觀察其方法的執(zhí)行順序:
[攔截器3]的before方法
[攔截器2]的before方法
[攔截器1]的before方法
Hello World
[攔截器1]的after方法
[攔截器2]的after方法
[攔截器3]的after方法
before方法按照最后一個攔截器到第一個攔截器的加載順序運(yùn)行,而after方法則按照從第一個攔截器到最后一個攔截器的加載順序運(yùn)行。
從代碼中可見,責(zé)任鏈模式的優(yōu)點(diǎn)在于我們可以在傳遞鏈上加入新的攔截器,增加攔截邏輯,其缺點(diǎn)是會增加代理和反射,而代理和反射的性能不高。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
Java 實(shí)現(xiàn)麥克風(fēng)自動錄音
這篇文章主要介紹了Java 實(shí)現(xiàn)麥克風(fēng)自動錄音的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12
PowerJob的OhMyClassLoader工作流程源碼解讀
這篇文章主要介紹了PowerJob的OhMyClassLoader工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Java的中l(wèi)ombok下的@Builder注解用法詳解
這篇文章主要介紹了Java的中l(wèi)ombok下的@Builder注解用法詳解,lombok注解在java進(jìn)行編譯時進(jìn)行代碼的構(gòu)建,對于java對象的創(chuàng)建工作它可以更優(yōu)雅,不需要寫多余的重復(fù)的代碼,在出現(xiàn)lombok之后,對象的創(chuàng)建工作更提供Builder方法,需要的朋友可以參考下2023-11-11
Java錯誤:進(jìn)行語法分析時已到達(dá)文件結(jié)尾的解決
這篇文章主要介紹了Java錯誤:進(jìn)行語法分析時已到達(dá)文件結(jié)尾的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
Spring?data?jpa緩存機(jī)制使用總結(jié)
這篇文章主要介紹了Spring?data?jpa緩存機(jī)制使用總結(jié),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
詳解IDEA中MAVEN項(xiàng)目打JAR包的簡單方法
本篇文章主要介紹了詳解IDEA中MAVEN項(xiàng)目打JAR包的簡單方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12

