当处理一个事件是根据这个事件的某个条件去决定哪个处理对象的时候可以考虑使用责任链模式.
具体我们从一个代码示范入手,定义一个抽象的处理者
public abstract class AbstractHandler {
public AbstractHandler nextHandler;
/**
* 处理请求,当Request Level 和 Handle Level相等就表明该请求交由该处理者处理
*/
public final void handleRequest(AbstractRequest request){
if (getHandleLevel() == request.getRequestLevel()){
handle(request);
}else {
if (nextHandler != null){
nextHandler.handle(request);
} else{
System.out.println("All of handler can not handle the request");
}
}
}
/**
* 获取处理对象的处理级别
* @return
*/
protected abstract int getHandleLevel();
/**
* 每个处理对象的具体处理方式
*/
protected abstract void handle(AbstractRequest request);
}
再定义一个抽象的请求
public abstract class AbstractRequest {
private Object obj;
public AbstractRequest(Object obj) {
this.obj = obj;
}
/**
* 获取处理内容的对象
*/
public Object getContent(){
return obj;
}
/**
* 获取请求级别
*/
public abstract int getRequestLevel();
}
下面分别定义3个实际的处理者和3个实际的请求
public class Handler1 extends AbstractHandler{
@Override
protected int getHandleLevel() {
return 1;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1 handle request : "+request.getRequestLevel());
}
}
public class Handler2 extends AbstractHandler{
@Override
protected int getHandleLevel() {
return 2;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler2 handle request : "+request.getRequestLevel());
}
}
public class Handler3 extends AbstractHandler{
@Override
protected int getHandleLevel() {
return 3;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler3 handle request : "+request.getRequestLevel());
}
}
public class Request1 extends AbstractRequest{
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest{
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
public class Request3 extends AbstractRequest{
public Request3(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 3;
}
}
最终调用
Handler1 handler1 = new Handler1();
Handler2 handler2 = new Handler2();
Handler3 handler3 = new Handler3();
/**
* 构建责任链
*/
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
Request1 request1 = new Request1("request 1");
Request2 request2 = new Request2("request 2");
Request3 request3 = new Request3("request 3");
handler1.handleRequest(request1);
handler1.handleRequest(request2);
handler3.handleRequest(request3);
输出:
01-13 21:33:44.684 22261-22261/? I/System.out: Handler1 handle request : 1
01-13 21:33:44.684 22261-22261/? I/System.out: Handler2 handle request : 2
01-13 21:33:44.684 22261-22261/? I/System.out: Handler3 handle request : 3
上面我们创建Request并交给Handler构建的一条责任链处理,当满足Request的Level和Handler的Level相等的情况就交由该Handler进行处理,这就是一个责任链的基本实现.
下面在再举一个实际栗子看看运用上面这套责任链模式代码.
目前小明出国出差回来,出差的经费是50000元,小明需要报销这笔经费,他首先找到他的组长处理报销问题,但是组长这边只能处理1000元以下的报销,组长表示找上面的部门主管批复,于是找到部门主管,部门主管只能处理5000以下的报销,于是部门主管找到经理批复,经理只能处理10000元以下的报销,于是经理找到老板,进行报销批复。处理报销经费事件这一连串人可以看作是一个责任链,我们可以用责任链模式去实现上面的需求.
先抽象领导
public abstract class Leader {
//上级领导
public Leader nextHandler;
public final void handleRequest(int money){
/**
* 如果报销经费小于该领导的处理范围,则处理.
*/
if (money < limit()){
handle(money);
} else {
/**
* 不满足交给上级领导进行处理
*/
if (null != nextHandler){
nextHandler.handleRequest(money);
}
}
}
/**
* 处理经费上限
* @return
*/
public abstract int limit();
/**
* 处理报销
* @param money
*/
protected abstract void handle(int money);
}
具体的四个领导
public class GroupLeader extends Leader{
@Override
public int limit() {
return 1000;
}
@Override
protected void handle(int money) {
System.out.println("组长批复报销 "+money+" 元");
}
}
public class Director extends Leader{
@Override
public int limit() {
return 5000;
}
@Override
protected void handle(int money) {
System.out.println("主管批复报销 "+money+"元");
}
}
public class Manager extends Leader{
@Override
public int limit() {
return 10000;
}
@Override
protected void handle(int money) {
System.out.println("经理批复报销 "+money+"元");
}
}
public class Boss extends Leader{
@Override
public int limit() {
return Integer.MAX_VALUE;
}
@Override
protected void handle(int money) {
System.out.println("老板批复报销"+money+"元");
}
}
最后调用
GroupLeader groupLeader = new GroupLeader();
Director director = new Director();
Manager manager = new Manager();
Boss boss = new Boss();
groupLeader.nextHandler = director;
director.nextHandler = manager;
manager.nextHandler = boss;
groupLeader.handleRequest(50000);
输出
01-13 21:48:40.181 22459-22459/? I/System.out: 老板批复报销50000元
其实责任链模式也并不是一定要按照上面那套模版代码去实现,关键是要突出处理一个事件的处理者再不满足处理该事件条件的情况下把事件传递给下一个处理者这种思想. 最后再来一个栗子,在Android开发中广播分为两种,一种是Normal Broadcast另外一种是Order Broadcast, 发送Normal Broadcast是所有注册该广播的广播接收者都能接收到。Order Broadcast是按照广播接收者优先级依次发送,接收到该广播的广播接收者可以选择是否继续向下传递,我们可以利用Order Broadcast这样的机制来实现一条责任链.
public class FirstBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int limit = intent.getIntExtra("limit",-1001);
if (limit == 1000){
String msg = intent.getStringExtra("msg");
Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
abortBroadcast();
} else {
Bundle b = new Bundle();
b.putString("new","Message from FirstReceiver");
setResultExtras(b);
}
}
}
public class SecondBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int limit = intent.getIntExtra("limit",-1001);
if (limit == 100){
String msg = intent.getStringExtra("msg");
//取上一个receiver的附加信息
Bundle b = getResultExtras(true);
String str = b.getString("new");
Toast.makeText(context,msg+" ----- "+str,Toast.LENGTH_SHORT).show();
abortBroadcast();
}else{
Bundle b = new Bundle();
b.putString("new","Message from SecondReceiver");
setResultExtras(b);
}
}
}
public class ThirdBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int limit = intent.getIntExtra("limit",-1001);
if (limit == 10){
String msg = intent.getStringExtra("msg");
Bundle b = getResultExtras(true);
String str = b.getString("new");
Toast.makeText(context,msg+" ---- "+str,Toast.LENGTH_SHORT).show();
abortBroadcast();
}else{
Bundle b = new Bundle();
b.putString("new","Message from ThirdReceiver");
setResultExtras(b);
}
}
}
在AndroidManifest.xml中申明这3个Receiver,并设置对应的权限值.
<receiver android:name=".broadcast.FirstBroadcastReceiver">
<intent-filter
android:priority="1000"
>
<action android:name="com.example.huangli.action.ORDER_BROADCAST"></action>
</intent-filter>
</receiver>
<receiver android:name=".broadcast.SecondBroadcastReceiver">
<intent-filter
android:priority="100"
>
<action android:name="com.example.huangli.action.ORDER_BROADCAST"></action>
</intent-filter>
</receiver>
<receiver android:name=".broadcast.ThirdBroadcastReceiver">
<intent-filter
android:priority="10"
>
<action android:name="com.example.huangli.action.ORDER_BROADCAST"></action>
</intent-filter>
</receiver>
最后调用:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendBroadcast();
}
private void sendBroadcast() {
Intent intent = new Intent();
intent.setAction("com.example.huangli.action.ORDER_BROADCAST");
intent.putExtra("limit", 100);
intent.putExtra("msg", "Message from MainActivity");
sendOrderedBroadcast(intent, null);
}
}
我们将limit设置成了100,它会在SecondBroadcastReceiver进行处理,实际效果大家可以试试。