前言
責任鏈模式自如其名,就是誰的責任誰來處理這個問題,但是對於這件問題只有一個請求入口,逐個傳遞達到結束請求的目的。其結構很像生活中的鐵鏈,由一個個小的橢圓形的圓環相連,將每一個圓環看做一個對象,每一個對象都擁有不同的處理邏輯,首端發出請求,這些對象就會按需求來看誰滿足處理這個請求的能力,沿着這個鏈結構逐個傳遞,最終解決問題。如果還不形象,我就舉一個例子,你找領導報銷10000元出差補助,你找了你的直接領導就是部門經理,然後部門經理又只能報銷2000以內,然後部門經理拿着你的報銷單就去找總監,總監又只能報銷5000以下,總監再去找經理,然後報銷通過了,這一個過程就闡述了這個模式。
使用場景
1,多個對象處理一類請求,但是請求到底是由那個對象來處理由對象本身能力決定。
2,項目中需要指定一組請求處理類。
角色扮演
Handler: 抽象處理類,申明一個處理方法,並保存下一個處理節點。
ConcreteHandler: 具體的處理類,對請求進行處理。
通常情況下,請求類還會進行類似的封裝,形成抽象Request類和ConcreteRequest類,這個抽象過程跟Handler完全一樣。
Demo
就前言提到的報銷問題做一個Demo。首先是抽象類Handler:
package com.demo.iterator;
/**
* Created by Daybreak on 2017/12/18.
*/
public abstract class Leader{
// 上級領導對於下一個處理節點
protected Leader nextLeader;
public Leader(Leader nextLeader){
this.nextLeader = nextLeader;
}
public final void handlerRequest(int money){
if (money < limit()) {
handler(money);
}else{
if (nextLeader != null){
nextLeader.handlerRequest(money);
}
}
}
/**
* 真正處理邏輯
* @param money
*/
protected abstract void handler(int money);
/**
* 當前領導的最大權限
* @return
*/
protected abstract int limit();
}
接着我們要定義階級關係了。
package com.demo.iterator;
import android.util.Log;
/**
* Created by Daybreak on 2017/12/18.
*/
public class GroupLeader extends Leader {
// 類名,用於日誌區分
public final static String CLASSNAME = GroupLeader.class.getSimpleName();
public GroupLeader(Leader nextLeader) {
super(nextLeader);
}
@Override
protected void handler(int money) {
Log.e(CLASSNAME,"部門經理爽快的給你報了");
}
@Override
protected int limit() {
return 2000;
}
}
package com.demo.iterator;
import android.util.Log;
/**
* Created by Daybreak on 2017/12/18.
*/
public class Director extends Leader {
public final static String CLASSNAME = Director.class.getSimpleName();
public Director(Leader nextLeader) {
super(nextLeader);
}
@Override
protected void handler(int money) {
Log.e(CLASSNAME,"總監爽快的報銷了");
}
@Override
protected int limit() {
return 5000;
}
}
package com.demo.iterator;
import android.util.Log;
/**
* Created by Daybreak on 2017/12/18.
*/
public class Manager extends Leader {
public final static String CLASSNAME = Manager.class.getSimpleName();
public Manager(Leader nextLeader) {
super(nextLeader);
}
@Override
protected void handler(int money) {
Log.e(CLASSNAME,"經理給你爽快的報了");
}
@Override
protected int limit() {
return 50000;
}
}
定義完ConcreteHandler類我們就可以簡單的使用了,來吧:
package com.demo.iterator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import com.example.daybreak.helloword.R;
public class ExpenseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expense);
// 列出所有階級關係
Manager manager = new Manager(null);
Director director = new Director(manager);
final GroupLeader groupLeader = new GroupLeader(director);
findViewById(R.id.account).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
groupLeader.handlerRequest(10000);
}
});
}
}
作爲員工報銷就找部門經理就行了,其他的就是等待結果了。
後記
Android有很多類似的模式,比如觸摸屏幕的監聽處理,再比如有序廣播的處理。責任鏈模式請求者只管請求然後坐等結果,這用語言描述就是解耦,這樣就提高了代碼的靈活性;但是同樣處理者太多首先是類文件會多,其次遍歷這個鏈的時間問題,怎麼也會影響其性能。