意图
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象练成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
实现
其中
- Handle定义一个处理请求的接口:(可选)实现后继续。
- ConcreteHandle处理它所负担的请求;可访问它的后继者;如果有可处理请求,就处理它,否则将该请求转发给后继者。
- Client向链上的具体处理处理者(ConcreteHandler)对象提交请求。
适用性
Chain of Responsibility模式适用于一下模式:
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 想在太明确指定接收者的情况下向多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
代码示例
场景:
假设开发一个邮件处理系统,该系统需要根据邮件的主题和内容进行不同的处理,例如:
- 如果邮件主题包含 "紧急",则立即发送给相关负责人。
- 如果邮件内容包含 "投诉",则转发给客服部门处理。
- 如果邮件内容包含 "广告",则自动标记为垃圾邮件。
- 如果以上条件都不满足,则将邮件归档。
实现:
可以使用责任链模式来设计这个系统。该模式的核心思想是将多个处理对象链接成一条链,当一个请求到来时,它会沿着链条传递,直到找到合适的处理对象为止。
java
// 抽象处理者
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(Email email);
}
// 具体处理者1:紧急邮件处理者
class UrgentHandler extends Handler {
@Override
public void handleRequest(Email email) {
if (email.getSubject().contains("紧急")) {
System.out.println("紧急邮件处理者处理邮件:" + email.getSubject());
} else {
nextHandler.handleRequest(email);
}
}
}
// 具体处理者2:投诉邮件处理者
class ComplaintHandler extends Handler {
@Override
public void handleRequest(Email email) {
if (email.getContent().contains("投诉")) {
System.out.println("投诉邮件处理者处理邮件:" + email.getSubject());
} else {
nextHandler.handleRequest(email);
}
}
}
// 具体处理者3:广告邮件处理者
class SpamHandler extends Handler {
@Override
public void handleRequest(Email email) {
if (email.getContent().contains("广告")) {
System.out.println("广告邮件处理者处理邮件:" + email.getSubject());
} else {
nextHandler.handleRequest(email);
}
}
}
// 具体处理者4:默认邮件处理者
class DefaultHandler extends Handler {
@Override
public void handleRequest(Email email) {
System.out.println("默认邮件处理者处理邮件:" + email.getSubject());
}
}
// 邮件类
class Email {
private String subject;
private String content;
public Email(String subject, String content) {
this.subject = subject;
this.content = content;
}
public String getSubject() {
return subject;
}
public String getContent() {
return content;
}
}
// 测试类
public class Main {
public static void main(String[] args) {
// 创建处理者链
Handler urgentHandler = new UrgentHandler();
Handler complaintHandler = new ComplaintHandler();
Handler spamHandler = new SpamHandler();
Handler defaultHandler = new DefaultHandler();
urgentHandler.setNextHandler(complaintHandler);
complaintHandler.setNextHandler(spamHandler);
spamHandler.setNextHandler(defaultHandler);
// 创建邮件
Email email1 = new Email("紧急:系统故障", "系统出现故障,请尽快处理");
Email email2 = new Email("投诉:产品质量问题", "产品质量存在问题,要求退货");
Email email3 = new Email("广告:免费送手机", "免费送手机,数量有限,快来抢购");
Email email4 = new Email("普通邮件", "这是一封普通邮件");
// 处理邮件
urgentHandler.handleRequest(email1);
urgentHandler.handleRequest(email2);
urgentHandler.handleRequest(email3);
urgentHandler.handleRequest(email4);
}
}
代码设计注释:
Handler
抽象类定义了处理请求的接口,并提供了一个setNextHandler
方法用于链接处理者。- 每个具体的处理者类都继承自
Handler
抽象类,并重写handleRequest
方法来实现自己的处理逻辑。 Email
类代表邮件对象,包含邮件的主题和内容。Main
类中创建了处理者链,并创建了不同的邮件对象,然后调用handleRequest
方法来处理这些邮件。