前言
责任链模式自如其名,就是谁的责任谁来处理这个问题,但是对于这件问题只有一个请求入口,逐个传递达到结束请求的目的。其结构很像生活中的铁链,由一个个小的椭圆形的圆环相连,将每一个圆环看做一个对象,每一个对象都拥有不同的处理逻辑,首端发出请求,这些对象就会按需求来看谁满足处理这个请求的能力,沿着这个链结构逐个传递,最终解决问题。如果还不形象,我就举一个例子,你找领导报销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有很多类似的模式,比如触摸屏幕的监听处理,再比如有序广播的处理。责任链模式请求者只管请求然后坐等结果,这用语言描述就是解耦,这样就提高了代码的灵活性;但是同样处理者太多首先是类文件会多,其次遍历这个链的时间问题,怎么也会影响其性能。