意图
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象练成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
实现
其中
- Handle定义一个处理请求的接口:(可选)实现后继续。
- ConcreteHandle处理它所负担的请求;可访问它的后继者;如果有可处理请求,就处理它,否则将该请求转发给后继者。
- Client向链上的具体处理处理者(ConcreteHandler)对象提交请求。
适用性
Chain of Responsibility模式适用于一下模式:
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 想在太明确指定接收者的情况下向多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
代码示例
场景:
假设开发一个邮件处理系统,该系统需要根据邮件的主题和内容进行不同的处理,例如:
- 如果邮件主题包含 "紧急",则立即发送给相关负责人。
- 如果邮件内容包含 "投诉",则转发给客服部门处理。
- 如果邮件内容包含 "广告",则自动标记为垃圾邮件。
- 如果以上条件都不满足,则将邮件归档。
实现:
可以使用责任链模式来设计这个系统。该模式的核心思想是将多个处理对象链接成一条链,当一个请求到来时,它会沿着链条传递,直到找到合适的处理对象为止。
// 抽象处理者
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 {@Overridepublic void handleRequest(Email email) {if (email.getSubject().contains("紧急")) {System.out.println("紧急邮件处理者处理邮件:" + email.getSubject());} else {nextHandler.handleRequest(email);}}
}// 具体处理者2:投诉邮件处理者
class ComplaintHandler extends Handler {@Overridepublic void handleRequest(Email email) {if (email.getContent().contains("投诉")) {System.out.println("投诉邮件处理者处理邮件:" + email.getSubject());} else {nextHandler.handleRequest(email);}}
}// 具体处理者3:广告邮件处理者
class SpamHandler extends Handler {@Overridepublic void handleRequest(Email email) {if (email.getContent().contains("广告")) {System.out.println("广告邮件处理者处理邮件:" + email.getSubject());} else {nextHandler.handleRequest(email);}}
}// 具体处理者4:默认邮件处理者
class DefaultHandler extends Handler {@Overridepublic 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
方法来处理这些邮件。