1.責(zé)任鏈模式(Chain of Responsibility)
責(zé)任鏈模式是一種設(shè)計(jì)模式。在責(zé)任鏈模式里,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來(lái)形成一條鏈。請(qǐng)求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶(hù)端并不知道鏈上的哪一個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使得系統(tǒng)可以在不影響客戶(hù)端的情況下動(dòng)態(tài)地重新組織和分配責(zé)任。
2.代碼實(shí)現(xiàn)
場(chǎng)景:當(dāng)我們計(jì)算某個(gè)數(shù)的階乘的時(shí)候,小的數(shù)據(jù)就可以用int來(lái)接收,稍微大點(diǎn)的用long來(lái)接收,再大一點(diǎn)的用BigInterger來(lái)接收。
- 處理者接口(Handler)
public interface Handler {
/**
* 傳入一個(gè)數(shù)字類(lèi)型的字符串,最后將其轉(zhuǎn)換為需要的類(lèi)型
* @param number
*/
void compuerMultiply(String number);
/**
* 指定下一個(gè)處理者
* @param handler
*/
void setNextHandler(Handler handler);
}
- 具體處理者(useInt)
public class UseInt implements Handler {
private Handler handler;
private int result=1;
@Override
public void compuerMultiply(String number) {
try{
int n = Integer.parseInt(number);
int i = 1;
while(i<=n){
result *=i;
if(result<=0){
System.out.println("超出int的能力范圍,int計(jì)算不了了");
handler.compuerMultiply(number);
return;
}
i++;
}
System.out.println(number+"的階乘"+result);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
- 具體處理者(useLong)
public class UseLong implements Handler {
private Handler handler;
private long result=1;
@Override
public void compuerMultiply(String number) {
try{
long n = Long.parseLong(number);
long i = 1;
while(i<=n){
result *=i;
if(result<=0){
System.out.println("超出long的能力范圍,long計(jì)算不了了");
handler.compuerMultiply(number);
return;
}
i++;
}
System.out.println(number+"的階乘"+result);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
- 具體處理者(UseBigInterger)
import java.math.BigInteger;
public class UseBigInterger implements Handler {
private Handler handler;
private BigInteger result=new BigInteger("1");
@Override
public void compuerMultiply(String number) {
try{
BigInteger n =new BigInteger(number);
BigInteger one =new BigInteger("1");
BigInteger i = one ;
while(i.compareTo(n)<=0){
result =result.multiply(i);
i = i.add(one );
}
System.out.println(number+"的階乘"+result);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
- 執(zhí)行Main方法
public class Main {
public static void main(String[] args) {
Handler useInt,useLong,useBig;
useInt = new UseInt();
useLong = new UseLong();
useBig = new UseBigInterger();
useInt.setNextHandler(useLong);
useLong.setNextHandler(useBig);
useInt.compuerMultiply("5");
useInt.compuerMultiply("19");
useInt.compuerMultiply("30");
}
}
- 運(yùn)行結(jié)果:

- 優(yōu)點(diǎn)
1、降低耦合度。它將請(qǐng)求的發(fā)送者和接收者解耦。
2、簡(jiǎn)化了對(duì)象。使得對(duì)象不需要知道鏈的結(jié)構(gòu)。
3、增強(qiáng)給對(duì)象指派職責(zé)的靈活性。通過(guò)改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,允許動(dòng)態(tài)地新增或者刪除責(zé)任。
4、增加新的請(qǐng)求處理類(lèi)很方便。- 缺點(diǎn):
1、不能保證請(qǐng)求一定被接收。
2、系統(tǒng)性能將受到一定影響,而且在進(jìn)行代碼調(diào)試時(shí)不太方便,可能會(huì)造成循環(huán)調(diào)用。
3、可能不容易觀察運(yùn)行時(shí)的特征,有礙于除錯(cuò)。- 使用場(chǎng)景:
1、有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體哪個(gè)對(duì)象處理該請(qǐng)求由運(yùn)行時(shí)刻自動(dòng)確定。
2、在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。
3、可動(dòng)態(tài)指定一組對(duì)象處理請(qǐng)求。
(總結(jié)參考:菜鳥(niǎo)教程)
當(dāng)前文集 :Java設(shè)計(jì)模式
代碼:GitHub