责任链模式(Chain Of Responsibility)
责任链模式主要提现在链上的,他的核心也在链上;是由多个处理者构成的一个链状处理线,沿着这么一条链传递处理请求,直到有对象处理请求为止。
类图:
这是一个已经实现了责任链模式的demo。有些地方写的不是很严谨我会在下面指出。
ICar:是请求对象的接口。
Car:具体的请求对象,里面定义相对应的请求状态和请求信息等。
Handler:抽象的请求处理类。
Start/Run/Stop:具体的请求处理对象,请求相对应的请求。
当一个汽车对象进行请求,假如请求是否可以停止,则进行一个链状传递请求,根据类型判断,从Start到Run在到Stop。当传递到Stop类的时候。开始处理,符合可以进行停止。这么一个就是链状的请求传递。
在使用责任链模式的时候需要注意:
1. 性能问题:每一次都是从链头传递到链尾,如果链比较长的情况下,性能就会有很大的问题。
2. 调试:责任链的调试不是很方便,这个的话如果大家使用的话就知道了。
责任链非常重要的几个方法:
handlerMessage方法:请求处理方法,用来判断当前的请求是否可以处理。
setNext:方法进行链的编排,下一个处理者的设置。
level:设置自己所能处理的级别。我在代码中是写死了,实际中可以使用一个类封装。相对就更灵活了。
response(或者是echo):具体的处理方法。名字的叫法有一些不一样。
代码实现:
public interface ICar {
public int getType();
public String getRequest();
}
public class Car implements ICar {
//定义一个级别描述现在的状况
private int type = 0 ;
private String request = "";
public Car(int _type, String _request){
this.type = _type;
switch (this.type) {
case 1:
this.request = "汽车的请求是" + _request;
break;
case 2:
this.request = "汽车的请求是" + _request;
break;
case 3:
this.request = "汽车的请求是" + _request;
break;
}
}
@Override
public int getType() {
return this.type;
}
@Override
public String getRequest() {
return this.request;
}
}
public abstract class Handler {
public final static int START_LEVEL_REQUEST = 1;
public final static int RUN_LEVEL_REQUEST = 2;
public final static int STOP_LEVEL_REQUEST = 3;
//能处理的级别
private int level = 0;
private Handler nextHandler;
//构造函数,每个类都要声明自己的处理级别.用于处理哪些请求
public Handler(int _level){
this.level = _level;
}
//判断请求是否属于你的
public final void HandlerMessage(ICar _car){
if(_car.getType() == this.level){
this.response(_car);
}else{
if(this.nextHandler != null){
this.nextHandler.HandlerMessage(_car);
}else{
System.out.println("没有后续环节了,车子已报废。");
}
}
}
/*
* 如果不属于你的请求、你应该找到下一个环节
* 汽车已经启动,在像启动环节询问的时候,应该告诉他你可以跑起来环节
*/
public void setNext(Handler _handler){
this.nextHandler = _handler;
}
//回应部分
protected abstract void response(ICar _car);
}
public class Start extends Handler {
public Start() {
super(Handler.START_LEVEL_REQUEST);
}
@Override
protected void response(ICar _car) {
System.out.println("-----------------汽车未启动,请示启动---------------- \n");
System.out.println(_car.getRequest());
System.out.println("-----------------汽车可以启动--------------- \n");
}
}
public class Run extends Handler {
public Run() {
super(Handler.RUN_LEVEL_REQUEST);
}
@Override
protected void response(ICar _car) {
System.out.println("-----------------汽车已启动,请示跑路---------------- \n");
System.out.println(_car.getRequest());
System.out.println("-----------------汽车可以跑路--------------- \n");
}
}
public class Stop extends Handler {
public Stop() {
super(Handler.STOP_LEVEL_REQUEST);
}
@Override
protected void response(ICar _car) {
System.out.println("-----------------汽车已跑路,请示停止---------------- \n");
System.out.println(_car.getRequest());
System.out.println("-----------------汽车可以停止--------------- \n");
}
}
public class Client {
public static void main(String args[]){
Handler start = new Start();
Handler run = new Run();
Handler stop = new Stop();
start.setNext(run);
run.setNext(stop);
ICar car = new Car(1,"我要启动汽车");
ICar car1 = new Car(3,"我要停止汽车");
start.HandlerMessage(car1);
start.HandlerMessage(car);
}
}
一般情况下会对client类进行封装,直接返回start对象。直接调用就可以了。
有一个使用场景,当一个用户注册,一种是注册会员用户,一种是注册游客用户。就可以使用一个入口,采用责任链的方式进行分别处理。