责任链模式
例子
中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父、既嫁从夫、夫 死从子”。也就是说,一位女性在结婚之前要听从于父亲,结婚之后要听从于丈夫,如果丈夫死了还要听从于儿子。(我不喜欢这个例子,还好现代已经好多了)
public interface IWomen {
/**
* 获得个人情况
* @return
*/
int getType();
/**
* 获取个人请示 逛街 约会 看电影
* @return
*/
String getRequest();
}
public class Women implements IWomen {
private int type = 0;
private String request = "";
public Women(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;
default:
}
}
@Override
public int getType() {
return this.type;
}
@Override
public String getRequest() {
return this.request;
}
}
public abstract class Handler {
public final static int FATHER_LEVEL_REQUEST = 1;
public final static int HUSBAND_LEVEL_REQUEST = 2;
public final static int SON_LEVEL_REQUEST = 3;
/**
* 能处理的级别
*/
private int level = 0;
/**
* 责任传递,下一个人责任人是谁
*/
private Handler nextHandler;
/**
* 每个类都要说明一下自己能处理哪些请求
* @param level
*/
public Handler(int level) {
this.level = level;
}
/**
* 一个女性(女儿、妻子或者是母亲)要求逛街,你要处理这个请求
*
* @param women
*/
public final void handleMessage(IWomen women) {
if (women.getType() == this.level) {
this.response(women);
} else {
if (this.nextHandler != null) {
//有后续环节,才把请求往后递送
this.nextHandler.handleMessage(women);
} else {
//已经没有后续处理人了,不用处理了
System.out.println("---没地方请示了,按不同意处理---\n");
}
}
}
/**
* 如果不属于你处理的请求,你应该让她找下一个环节的人,如女儿出嫁了, * 还向父亲请示是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示
*/
public void setNext(Handler _handler) {
this.nextHandler = _handler;
}
/**
* 有请示那当然要回应
*
* @param women
*/
protected abstract void response(IWomen women);
}
public class Father extends Handler {
/**
* 每个类都要说明一下自己能处理哪些请求
*/
public Father() {
super(Handler.FATHER_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------妻子向丈夫请示-------");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是:同意\n");
}
}
public class Husband extends Handler {
public Husband() {
super(Handler.HUSBAND_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------妻子向丈夫请示-------");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是:同意\n");
}
}
public class Son extends Handler {
public Son() {
super(Handler.SON_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------母亲向儿子请示-------");
System.out.println(women.getRequest());
System.out.println("儿子的答复是:同意\n");
}
}
public class Client {
public static void main(String[] args) {
//随机挑选几个女性
Random rand = new Random();
List<IWomen> arrayList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
arrayList.add(new Women(rand.nextInt(4), "我要出去逛街"));
}
//定义三个请示对象
Handler father = new Father();
Handler husband = new Husband();
Handler son = new Son();
//设置请示顺序
father.setNext(husband);
husband.setNext(son);
arrayList.forEach(father::handleMessage);
}
}
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
public class Level {
//定义一个请求和处理等级
}
public class Request {
public Level getRequestLevel(){
return null;
}
}
public class Response {
// 处理者返回的数据
}
public abstract class Handler {
private Handler nextHandler;
public final Response handlerMessage(Request request) {
Response response = null;
if (this.getHandlerLevel().equals(request.getRequestLevel())) {
response = this.echo(request);
} else {
if (this.nextHandler != null) {
response = this.nextHandler.handlerMessage(request);
} else { //没有适当的处理者,业务自行处理 }
}
}
return response;
}
/**
* 设置下一个处理者是谁
* @param handler
*/
public void setNext(Handler handler) {
this.nextHandler = handler;
}
/**
* 每个处理者都有一个处理级别
* @return
*/
protected abstract Level getHandlerLevel();
/**
* 每个处理者都必须实现处理任务
* @param request
* @return
*/
protected abstract Response echo(Request request);
}
public class ConcreteHandler1 extends Handler{
@Override
protected Level getHandlerLevel() {
return null;
}
@Override
protected Response echo(Request request) {
return null;
}
}
public class ConcreteHandler2 extends Handler{
@Override
protected Level getHandlerLevel() {
return null;
}
@Override
protected Response echo(Request request) {
return null;
}
}
public class ConcreteHandler3 extends Handler{
@Override
protected Level getHandlerLevel() {
return null;
}
@Override
protected Response echo(Request request) {
return null;
}
}
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
//设置链中的阶段顺序1-->2-->3
handler1.setNext(handler2); handler2.setNext(handler3);
//提交请求,返回结果
Response response = handler1.handlerMessage(new Request());
}
}
优点
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌(例如在J2EE项目开发中,可以剥离出无状态Bean由责任链处理),两者解耦,提高系统的灵活性。
缺点
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
注意事项
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。