* 24种设计模式——责任链模式

本文介绍了责任链模式的概念、实现及应用场景。通过一个古代妇女请求逛街的例子,详细解释了如何使用责任链模式处理请求,以及其背后的原理。文章还讨论了模式的优点、缺点,并给出了一些实用建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、古代妇女的枷锁——三从四德

结婚前听从于父亲。

结婚后听从于丈夫。

夫死后听众于儿子。

这导致女人的状态和请求对象死死耦合在一起,如果婚后还请求于父亲又该如何呢?

这就使用责任链,将请求传递到下一个责任点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还是普通用户信息,统一传递到一个入口,通过责任链来完成任务的处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值