责任链是一种行为设计模式,可让您沿着处理程序链传递请求。收到请求后,每个处理程序决定要么处理请求,要么将其传递给链中的下一个处理程序。
想象一下,您正在开发一个在线订购系统。您希望仅授权用户访问系统。因此,您在订单进入订购系统之前添加了检查。随着时间的推移,您添加了更多检查,包括验证请求数据、来自同一 IP 地址的重复失败请求,以及在可以将请求输入在线订购系统之前检查缓存响应。
当您向代码添加更多检查时,它会变得臃肿。
责任链设计模式
责任链涉及将某些行为转换为称为处理程序的独立对象。我们应该将每个检查提取到它自己的类中,并使用一个方法来执行它。此方法接收请求及其数据作为参数。
这种模式建议将这些处理程序链接在一起。在每个链接的处理程序中,都有一个字段用于存储对链中下一个处理程序的引用。处理程序除了处理请求外,还沿着链传递请求。请求沿着链路由,直到所有处理程序都有机会处理它们。
此外,处理程序可以决定不将请求进一步向下传递,从而有效地停止进一步的处理。
UML 类图
实施步骤
- 声明处理程序接口并描述处理请求的方法的签名。确定客户端如何将请求数据传递给方法。将请求转换为对象并将其作为参数传递给处理方法是最灵活的处理方式。
- 可能值得创建一个派生自处理程序接口的抽象处理程序类,以消除具体处理程序中的重复样板代码。该类应该有一个字段用于存储对链中下一个处理程序的引用。
- 创建具体的处理程序子类并一一实现它们的方法。当收到请求时,每个处理程序应做出两个决定:
* 是否处理请求。
* 是否转发请求。
4.客户端既可以自己组装链,也可以从其他对象接收预先构建的链。链中的任何处理程序都可以由客户端触发,而不仅仅是第一个。它将沿着链传递,直到某些处理程序拒绝进一步传递它或直到它到达末端。
源代码实现
处理程序为所有具体处理程序声明一个公共接口。它通常只包含一个处理请求的方法,但有时它也可能包含一个设置下一个处理程序的方法。
package com.learncsdesign;
public interface Handler {
public void setNext(Handler handler);
public void handle(number num);
}
Base Handler 是一个可选类,您可以在其中放置所有处理程序类通用的样板代码。 通常,此类定义一个字段来存储对下一个处理程序的引用。
package com.learncsdesign;
public abstract class BaseHandler implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handle(Number num) {
if (next != null) {
next.handle(num);
}
}
}
具体处理程序包含处理请求的实际代码。 收到请求后,每个处理程序都必须决定是否处理它,此外,还要决定是否沿着链传递它。
NegativeNumberHandler 类处理负数。
package com.learncsdesign;
public class NegativeNumberHandler extends BaseHandler {
public void handle(Number num) {
if (num.longValue() < 0) {
System.out.println("Processing negative number " num.longValue());
} else {
super.handle(num);
}
}
}
PositiveNumberHandler 类处理正数。
package com.learncsdesign;
public class PositiveNumberHandler extends BaseHandler {
public void handle(Number num) {
if (num.longValue() > 0) {
System.out.println("Processing positive number " num.longValue());
} else {
super.handle(num);
}
}
}
zeroNumberHandler 类处理零数字。
package com.learncsdesign;
public class ZeroNumberHandler extends BaseHandler {
public void handle(Number num) {
if (num.longValue() == 0) {
System.out.println("Processing zero number " num.longValue());
} else {
super.handle(num);
}
}
}
客户端可以只组合一次链或动态组合它们,具体取决于应用程序的逻辑。
package com.learncsdesign;
public class CoRClient {
public static void main(String[] args) {
Handler h1 = new PositiveNumberHandler();
Handler h2 = new NegativeNumberHandler();
Handler h3 = new ZeroNumberHandler();
h1.setNext(h2);
h2.setNext(h3);
h1.handle(0);
h1.handle(100);
h1.handle(-10);
}
}
// Output
Processing zero number 0Processing positive number 100Processing negative number -10
何时应用责任链设计模式
- 每当您的程序希望以各种方式处理不同类型的请求,但事先不知道请求的类型及其顺序时,请使用责任链模式。
- 当必须以特定顺序执行多个处理程序时,请使用此模式。
- 当处理程序的顺序及其集合应该在运行时发生变化时,请使用此模式。
责任链设计模式的优点
- 可以控制处理请求的顺序。
- 您可以将调用操作的类与执行它们的类分离。
- 可以使用新的处理程序扩展应用程序,而不会破坏现有的客户端代码。
如果你喜欢这篇文章,别忘了鼓掌。
,