一、古代妇女的枷锁——三从四德
结婚前听从于父亲。
结婚后听从于丈夫。
夫死后听众于儿子。
这导致女人的状态和请求对象死死耦合在一起,如果婚后还请求于父亲又该如何呢?
这就使用责任链,将请求传递到下一个责任点nextHandler
从类图上看到,三个实现类Father、Husband、Son只要实现构造函数和父类中的抽象方法response就可以了,具体由谁处理女性提出的请求,都已经转移到Handler抽象类中。
抽象处理者一般三个职责:
1)定义一个请求的处理方法handlerMessage,唯一对外开放的方法。
2)定义一个链的编排方法setNext,设置下一个处理者
3)定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务echo。
1. 有处理权的人员接口
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;
//每个类都要说明一下自己能处理哪些请求
public Handler(int _level) {
this.level = _level;
}
//一个女性(女儿、妻子或者是母亲)要求逛街,你要处理这个请求
public final void HandlerMessage(IWomen women){
if(women.getType()==this.level){
this.response(women);
}else{
if(this.nextHandler!=null){ //有后续环节,才把请求往后递送
this.nextHandler.HandlerMessage(women);
}else{ //已经没有后续处理人了,不用处理了
System.out.println("---没有地方请求了,按不同意处理---");
}
}
}
/*
* 如果不属于你处理的请求,你应该让她找下一个环节的人,如女儿出嫁了,还向父亲请求是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示
*/
public void setNext(Handler _handler){
this.nextHandler = _handler;
}
//有请求那当然要回应
protected abstract void response(IWomen women);
}
2. 父亲类
public class Father extends Handler{
//父亲只处理女儿的请求
public Father() {
super(Handler.FATHER_LEVEL_REQUEST);
}
//父亲的答复
protected void response(IWomen women) {
System.out.println("---女儿向父亲请求---");
System.out.println(women.getRequest());
System.out.println("父亲的答复是:同意");
}
}
3. 丈夫类
public class Husband extends Handler{
//丈夫只处理妻子的请求
public Husband() {
super(Handler.HUSBAND_LEVEL_REQUEST);
}
//丈夫请求的答复
protected void response(IWomen women) {
System.out.println("---妻子向丈夫请示---");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是:同意");
}
}
4. 儿子类
public class Son extends Handler{
//儿子只能处理母亲的请求
public Son() {
super(Handler.SON_LEVEL_REQUEST);
}
//儿子的答复
protected void response(IWomen women) {
System.out.println("---母亲向儿子请示---");
System.out.println(women.getRequest());
System.out.println("儿子的答复是:同意");
}
}
5. 女性接口
public interface IHandler {
//一个女性(女儿、妻子或者母亲)要求逛街,你要处理这个请求
public void HandlerMessage(IWomen women);
}
6. 女性类
public class Women implements IWomen{
/*
* 通过一个int类型的参数来描述妇女的个人状况
* 1--未出嫁
* 2--出嫁
* 3--夫死
*/
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;
}
//this.request = request;
}
//获得自己的状况
public int getType() {
return this.type;
}
//获得自己的请求
public String getRequest() {
return this.request;
}
}
7. 场景类
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);
for(IWomen women:arrayList){
father.HandlerMessage(women);//都是从father开始,不是就转下一个,只要请求父亲就可以了,该父亲处理就处理,不该父亲处理就传下一个
}
}
}
二、责任链模式的定义
责任链模式的核心在"链"上,"链"是由多个处理者Concretehandler组成的。我们先来看抽象Handler类。
1. 抽象处理者
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;
}
//设置下一个处理者是谁
public void setNext(Handler _handler){
this.nextHandler = _handler;
}
//每个处理者都有一个处理级别
protected abstract Level getHandlerLevel();
//每个处理者都必须实现处理任务
protected abstract Response echo(Request request);
}
抽象处理者一般三个职责:
1)定义一个请求的处理方法handlerMessage,唯一对外开放的方法。
2)定义一个链的编排方法setNext,设置下一个处理者
3)定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务echo。
2. 具体处理者
public class ConcreteHandler1 extends Handler{
//设置自己的处理级别
protected Level getHandlerLevel() {
//设置自己的处理级别
return null;
}
//定义自己的处理逻辑
protected Response echo(Request request) {
//完成处理逻辑
return null;
}
}
&public class ConcreteHandler2 extends Handler{
//设置自己的处理级别
protected Level getHandlerLevel() {
//设置自己的处理级别
return null;
}
//定义自己的处理逻辑
protected Response echo(Request request) {
//完成处理逻辑
return null;
}
}
&
public class ConcreteHandler3 extends Handler{
//设置自己的处理级别
protected Level getHandlerLevel() {
//设置自己的处理级别
return null;
}
//定义自己的处理逻辑
protected Response echo(Request request) {
//完成处理逻辑
return null;
}
}
3. Level类负责定义请求和处理级别
public class Level {
//定义一个请求和处理等级
}
4. Request类负责封装请求
public class Request {
//负责封装请求
//请求等级
public Level getRequestLevel(){
return null;
}
}
5. Response类负责封装链中返回的结果
public class Response {
//封闭链中返回的结果
}
6. 场景类
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());
}
}
实际应用中,一般会有一个封装类对责任模式进行封装,也就是替代Client类,直接返回链中的第一个处理者,具体链的设置不需要高层次模块关系,这样,更简化了高层次模块的调用,减少模块间的耦合,提高系统的灵活性。三、责任链模式的应用
1. 优点
将请求和处理分开,请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌。
2. 缺点
性能问题,每个请求都是从链头遍历到链尾,当链比较长时,性能是一个问题。还有调试不方便。
3. 注意事项
避免出现超长链,可在Handler中设置一个最大节点数量进行判定。
四、最佳实践
1. 银行在办理客户存款币种时,有人民币、美元、欧元、日元等,不管传过来的是什么币,都从第一种币开始判定,这就可用责任链来处理请求
2. 处理VIP用户注册和普通用户注册,不管传的VIp还是普通用户信息,统一传递到一个入口,通过责任链来完成任务的处理。