【设计模式十九之责任链模式】责任链模式详解

细说责任链模式

提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041


细说责任链模式

想一想你的公司里面的是不是有这样的制度,你要请假,如果你要是请一天假的话,直接找你的直接主管批就行了,如果你请三天假的话,这个时候可能就要你部门的主管批了,如果你想请更长时间的假的话,这个时候可能就需要找到总监或者更高级别的人批示了。每个领导所管辖的范围其实都是有限的。这其实就是责任链模式。每个领导的责任宽度不一样,在请假的批示中,如果某个领导不批的话,那流程也就走完了。

定义

责任链模式:责任链模式是使多个对象都有机会去处理请求,从而避免了请求的发送者与接受者之间的耦合关系。使这些对象像一条链一样传递下去,直到有对象能够处理它为止。
所以:责任链模式,其实就是:要么承担责任做出回应,要么向下传递请求,最终会有环节做出回应
责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心;同时责任链模式也可以做为一种补救模式来使用

UML模型

在这里插入图片描述
责任链模式其实重点是这个链,通过ConcreteHandler传递来决定究竟是谁来具体来处理。

场景

场景一

设计模式之禅中的案例,古代女子的三从四德,在家从父,出嫁从夫,夫死从子,即未出嫁的女子,在家里有什么事情一般是请求父亲的指示,而出嫁的女子,一般需要听从丈夫的话,当丈夫去世之后,女子一般是听儿子的话,通过不同阶段的女子,其处理的对象是不一样的。者也就是责任链模式的一种应用场景,最开始从父亲一级传递到丈夫一级,然后再传递到儿子一级。直到某一级能够处理相关业务。代码参考代码一

场景二

在android四大组件中,有一个叫做有序广播的技术,广播这种东西是辐射化的,即只要注册了广播都可以收到,但是有序广播则决定了广播接受的顺序,即有优先级之分也可以被中间拦截,当一级广播收到之后,决定是自己处理还是继续往下广播,二级广播收到一级广播发来的信息后,决定是自己处理,还是继续分发,因此这也是一种在android实际应用场景中经常会遇到的责任链模式的一种系统应用场景。

代码

代码一
package src.com.zzf.designpattern.chainofresponsibilitypattern.demo2;

import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen;

public abstract class Handler {
	private int level;
	private Handler nextHandler;
	
	public  Handler(int level) {
		this.level = level;
	}
	
	public void setNextHandler(Handler mHandler){
		this.nextHandler = mHandler;
	}
	
	public void  HandlerMessage(IWomen mWomen) {
		if (mWomen.getType() == this.level) {
			this.response(mWomen);
		}else {
			if (this.nextHandler != null) {
				this.nextHandler.HandlerMessage(mWomen);
			}else {
				System.out.println("----------没地方请示-----------");
			}
		}
	}
	
	public abstract void response(IWomen mWomen);
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo2;

import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen;

public class FatherHandler extends Handler{

	public FatherHandler() {
		super(1);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void response(IWomen mWomen) {
		// TODO Auto-generated method stub
		System.out.println("--------女儿向父亲请示-------");
		System.out.println(mWomen.getRequest());
		System.out.println("父亲的答复是:同意\n");
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo2;

import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen;

public class HusbandHandler extends Handler{

	public HusbandHandler() {
		super(2);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void response(IWomen mWomen) {
		// TODO Auto-generated method stub
		System.out.println("--------妻子向丈夫请示-------");
		System.out.println(mWomen.getRequest());
		System.out.println("丈夫的答复是:同意\n");
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo2;

import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen;

public class SonHandler extends Handler{

	public SonHandler() {
		super(3);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void response(IWomen mWomen) {
		// TODO Auto-generated method stub
		System.out.println("--------母亲向儿子请示-------");
		System.out.println(mWomen.getRequest());
		System.out.println("儿子的答复是:同意\n");
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo1;


public interface IWomen {
	
	public int getType();
	public String getRequest();
	
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo1;

public class Women implements IWomen {

	private int type = 0;
	private String request = "";

	public Women(int type, String request) {
		this.type = type;
		this.request = request;
		// 为了显示好看点,我在这里做了点处理

		switch (this.type) {
		case 1:
			this.request = "女儿的请求是:" + request;
			break;
		case 2:
			this.request = "妻子的请求是:" + request;
			break;
		case 3:
			this.request = "母亲的请求是:" + request;
			break;
		default:
				break;

		}
	}

	public int getType() {
		// TODO Auto-generated method stub
		return type;
	}

	public String getRequest() {
		// TODO Auto-generated method stub
		return request;
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo2;


import java.util.ArrayList;
import java.util.Random;

import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen;
import src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.Women;


/**
 * 责任链模式,其实就是:要么承担责任做出回应,要么向下传递请求,最终会有环节做出回应,
 * 责任链模式角色分布:
 * Handler:抽象类,定义出来所有责任人的类型,
 * ConcreteHandler:定义出具体的相关责任人
 * Request:需要处理的相关事件类
 * 
 * @author Administrator
 *  责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请
	求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不
	用知道到底是需要谁来处理的,这是责任链模式的核心
	;同时责任链模式也可以做为一种补救模式来使用
	
	
	注意责任链模式与广播链模式之间的一些区别
 */
public class TestMian {
	public static void main(String[] args) {
		//随机挑选几个女性
		Random rand = new Random();
		ArrayList<src.com.zzf.designpattern.chainofresponsibilitypattern.demo1.IWomen> arrayList = new ArrayList();
		for(int i=0;i<5;i++){
			arrayList.add(new Women(rand.nextInt(4),"我要出去逛街"));
		}

		Handler mHandler = new FatherHandler();
		Handler mHandler2 = new HusbandHandler();
		SonHandler sonHandler = new SonHandler();
		
		mHandler.setNextHandler(mHandler2);
		mHandler2.setNextHandler(sonHandler);
		
		for(IWomen w:arrayList){
			mHandler.HandlerMessage(w);
		}
	}
}

代码二

一级广播的实现

public class FirstReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int limit = intent.getIntExtra("limit", -10001);
        //如果限制值为10000,则处理,否则交给下一个receiver处理
        if(limit == 10000) {
            String msg = intent.getStringExtra("msg");
            Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
            abortBroadcast();
        } else {
            //添加信息发送给下一个Receiver
            Bundle b = new Bundle();
            b.putString("new","Message From FisrtReceiver");
            setResultExtras(b);
        }
    }
}

二级广播的实现

public class SecondReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int limit = intent.getIntExtra("limit", -10001);
        //如果限制值为1000,则处理,否则交给下一个receiver处理
        if(limit == 1000) {
            String msg = intent.getStringExtra("msg");
            Bundle b = getResultExtra(true);
            String str = b.getString("new");
            Toast.makeText(context,msg + "-----",Toast.LENGTH_SHORT).show();
            abortBroadcast();
        } else {
            //添加信息发送给下一个Receiver
            Bundle b = new Bundle();
            b.putString("new","Message From SecondReceiver");
            setResultExtras(b);
        }
    }
}

注册广播

<receiver android:name=".broadcast.FirstReceiver">
    <intent-filter android:priority="10000">
    </action name="com.action.ORDER_BROADCAST">
    </intent-filter>
 
</receiver>
 
 
<receiver android:name=".broadcast.SecondReceiver">
    <intent-filter android:priority="1000">
    </action name="com.action.ORDER_BROADCAST">
    </intent-filter>
 
</receiver>

测试代码就暂时不写了,android发送广播的代码。简单的很

基于UML的代码
package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public enum Level {
	FIRST_LEVEL,
	SECOND_LEVEL,
	THIRD_LEVEL
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class Request {
	//请求的等级
	public Level getRequestLevel(){
		return Level.THIRD_LEVEL;
	}
	String request;
	
	public Request(String _request){
		this.request = _request;
	}
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class Response {
	private String responce;
	public Response(String _responce){
		this.responce = _responce;
	}
	
	public void toResult(){
		System.out.println("处理的请求是:"+responce);
	}
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public abstract class Handler {
	private Handler nextHandler;
	
	//设置下一个处理的对象
	public void setNext(Handler _handler){
		this.nextHandler = _handler;
	}
	//每个处理者都有个处理的级别
	protected abstract Level getHandlerLevel();
	
	//每个处理者都必须去实现处理任务
	protected abstract Response echo(Request request);
	
	//每个处理者都必须对请求做出处理
	public final Response handleMessage(Request request){
		Response response = null;
		//判断是否是自己处理的级别
		if(this.getHandlerLevel().equals(request.getRequestLevel())){
			response = this.echo(request);
		}else{
			if(this.nextHandler != null){
				response = this.nextHandler.handleMessage(request);
			}else{
				//没有适当处理者,业务自行处理
			}
		}
		return response;
	}
}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class ConcreteHandler1 extends Handler{

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return Level.FIRST_LEVEL;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return new Response(this.getClass().getName()+"\t"+request.getRequestLevel());
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class ConcreteHandler2 extends Handler{

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return Level.SECOND_LEVEL;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return new Response(this.getClass().getName()+request.getRequestLevel()));
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class ConcreteHandler3 extends Handler{

	@Override
	protected Level getHandlerLevel() {
		// TODO Auto-generated method stub
		return Level.THIRD_LEVEL;
	}

	@Override
	protected Response echo(Request request) {
		// TODO Auto-generated method stub
		return new Response(this.getClass().getName()+request.getRequestLevel());
	}

}

package src.com.zzf.designpattern.chainofresponsibilitypattern.demo3;

public class Test {
	public static void main(String[] args) {
		Handler concreteHandler1 = new ConcreteHandler1();
		Handler concreteHandler2 = new ConcreteHandler2();
		Handler concreteHandler3 = new ConcreteHandler3();
		
		concreteHandler1.setNext(concreteHandler2);
		concreteHandler2.setNext(concreteHandler3);
		Response response = concreteHandler1.handleMessage(new Request("发送请求"));
		response.toResult();
	}
}

责任链模式应用和注意事项

责任链模式在java或者android中的应用是非常广泛的,在android中的事件传递,广播。在javaEE中的servlet的过滤器Filter等都有应用。

责任链模式非常显著的将请求和结果进行了分离,由每一级决定谁去处理,处理者则不需要去了解具体实现类的全貌。但是它也会带来性能问题,即每一个请求下去,如果链比较长,这个时候不可避免的会影响性能
责任链模式中setNext函数尽可能的添加约束,超过这约束之后,则不允许建立连接,避免无意识的去破坏系统的性能




欢迎继续访问,我的博客
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值