责任链模式的定义
责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
模型:
- Hander:抽象处理者
- ConcreteHander:具体处理者
下面模型代码如下:
1.设计等级类
public class Level {
private int level=1;
public Level(int level){
this.level=level;
}
public int getLevel() {
return level;
}
}
2.请求类
public class MyRequest {
Level level;
public MyRequest(Level level){
this.level=level;
}
public int getLevel(){
return level.getLevel();
}
}
3.响应类
public class Response {
private String message;
public Response(String message) {
Log.d("qzs","处理完成");
this.message = message;
}
public String getMessage() {
return message;
}
}
4.抽象处理者类
public abstract class AbstractHandler {
//判断下一个处理者是谁
private AbstractHandler nextHandler = null;
public final Response handlerRequest(MyRequest request) {
Response response = null;
if(this.getHandlerLevel()==request.getLevel()) {
response = this.response(request);
}else {
if(this.nextHandler != null) {
Log.d("qzs","转到下一个处理者中...");
response = this.nextHandler.handlerRequest(request);
}else {
Log.d("qzs","后面没有处理请求了...");
}
}
return response;
}
public void setNextHandler(AbstractHandler handler) {
nextHandler = handler;
}
//拿到等级
protected abstract int getHandlerLevel();
//响应
protected abstract Response response(MyRequest request);
}
5.定义具体的处理者
这里定义了两个:
public class ConcreteHandlerA extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 0;
}
@Override
protected Response response(MyRequest request) {
Log.d("qzs","正在处理中“ConcreteHandlerA");
return new Response("响应处理结果A") ;
}
}
public class ConcreteHandlerB extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 1;
}
@Override
protected Response response(MyRequest request) {
Log.d("qzs","正在处理中“ConcreteHandlerB");
return new Response("响应处理结果B") ;
}
}
6.调用:
前提是A到B组成了一个链,并且上面A的等级是0,B是1;发出的请求先经过A如果不能处理就交给B:
AbstractHandler handler1=new ConcreteHandlerA();
AbstractHandler handler2=new ConcreteHandlerB();
//A到B组成一个链
handler1.setNextHandler(handler2);
Response response=handler1.handlerRequest(new MyRequest(new Level(1)));
上面代码我传送的等级是1,结果应该是由B解决的,下面是运行结果:
如果你传入的等级不在A和B的范围,运行结果如下:
说明没有适合的了。
实例说明
如果上面的定义不是很明白,下面直接实例说明一下。
例子:家里的小孩想出去玩,需要请示一下,这里规定一级请示爸爸,爸爸同意了就可以出去玩了;如果爸爸不在家就请示(二级)妈妈,妈妈同意了也可以出去玩;如果都不在家就不允许出去玩。
1.编写等级类,响应类,请求类
这些都没有变化可以直接去上面看就可以了。
2.抽象处理类:
public abstract class AbstractHandler {
//判断下一个处理者是谁
private AbstractHandler nextHandler = null;
public final Response handlerRequest(MyRequest request) {
Response response = null;
if(this.getHandlerLevel()==request.getLevel()) {
response = this.response(request);
}else {
if(this.nextHandler != null) {
Log.d("qzs","转到下一个处理者中...");
response = this.nextHandler.handlerRequest(request);
}else {
Log.d("qzs","爸爸妈妈不在家...");
}
}
return response;
}
public void setNextHandler(AbstractHandler handler) {
nextHandler = handler;
}
//拿到等级
protected abstract int getHandlerLevel();
//响应
protected abstract Response response(MyRequest request);
}
3.具体处理者
public class Father extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 1;
}
@Override
protected Response response(MyRequest request) {
Log.d("qzs","正在处理中“Father”");
Log.d("qzs","爸爸同意孩子出去玩了");
return new Response("") ;
}
}
public class Mother extends AbstractHandler{
@Override
protected int getHandlerLevel() {
return 2;
}
@Override
protected Response response(MyRequest request) {
Log.d("qzs","正在处理中“Mother”");
Log.d("qzs","妈妈同意孩子出去玩了");
return new Response("") ;
}
}
4.调用
如果传入的等级1:
AbstractHandler handler1=new Father();
AbstractHandler handler2=new Mother();
//先问爸爸,爸爸不在家再问妈妈
handler1.setNextHandler(handler2);
Response response=handler1.handlerRequest(new MyRequest(new Level(1)));
运行结果:
传入其他的等级也可以,这个大家可以自己去试一试。
责任链模式的优缺点及其他
1.优点
- 耦合度降低,请求和处理是分开的
2.缺点
- 责任链太长或者每条链判断处理的时间太长会影响性能。特别是递归循环的时候 不一定被处理,每个职责类的职责很明确,这就需要对写默认的处理了