细说责任链模式
提示:
博主:章飞 _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函数尽可能的添加约束,超过这约束之后,则不允许建立连接,避免无意识的去破坏系统的性能
欢迎继续访问,我的博客