详解Java实现设计模式之责任链模式
一、概述
责任链模式(Chain of Responsibility Pattern)是一种对象行为型设计模式,其作用是减少请求发送者与接收者之间的耦合,通过使多个对象都有机会处理请求来解决请求的发送者和接收者之间的耦合关系。通常情况下,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,它会把相同的请求传递给下一个接收者,以此类推,形成责任链。
二、优缺点
优点:
- 多个对象可以处理同一个请求,具有很好的灵活性和扩展性。
- 请求的发送者和接收者解耦,两者不存在直接关联。
- 更好的封装性和可维护性,责任链只需要关心自己的处理对象,不关心其他对象。
缺点:
- 责任链长度过长,可能会影响责任链传递的效率。
- 如果责任链节点没有被正确配置,可能会造成循环调用或者死循环,导致系统崩溃。
三、示例说明
示例一
场景描述:一个公司有3个部门,人事部、财务部和技术部,每个部门有一个负责人,员工请假需要先向其所在部门的负责人提交请假申请,如果负责人无法批准,则需要上级领导处理。
// 申请表
class LeaveRequest {
private String name; // 姓名
private int days; // 请假天数
public LeaveRequest(String name, int days) {
this.name = name;
this.days = days;
}
public String getName() {
return name;
}
public int getDays() {
return days;
}
}
// 抽象处理者
interface Handler {
// 处理请求
boolean handleRequest(LeaveRequest leaveRequest);
// 设置下一个处理者
void setNextHandler(Handler handler);
}
// 具体处理者-人事部负责人
class PersonnelHandler implements Handler {
private Handler nextHandler;
@Override
public boolean handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDays() <= 3) {
System.out.println("人事部负责人批准" + leaveRequest.getName() + "的请假申请,天数为" + leaveRequest.getDays() + "天");
return true;
} else {
if (nextHandler != null) {
return nextHandler.handleRequest(leaveRequest);
} else {
return false;
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}
}
// 具体处理者-财务部负责人
class FinanceHandler implements Handler {
private Handler nextHandler;
@Override
public boolean handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDays() <= 5) {
System.out.println("财务部负责人批准" + leaveRequest.getName() + "的请假申请,天数为" + leaveRequest.getDays() + "天");
return true;
} else {
if (nextHandler != null) {
return nextHandler.handleRequest(leaveRequest);
} else {
return false;
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}
}
// 具体处理者-技术部负责人
class TechnicalHandler implements Handler {
private Handler nextHandler;
@Override
public boolean handleRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDays() <= 7) {
System.out.println("技术部负责人批准" + leaveRequest.getName() + "的请假申请,天数为" + leaveRequest.getDays() + "天");
return true;
} else {
if (nextHandler != null) {
return nextHandler.handleRequest(leaveRequest);
} else {
return false;
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}
}
// 责任链客户端
public class Client {
public static void main(String[] args) {
Handler personnelHandler = new PersonnelHandler();
Handler financeHandler = new FinanceHandler();
Handler technicalHandler = new TechnicalHandler();
personnelHandler.setNextHandler(financeHandler);
financeHandler.setNextHandler(technicalHandler);
LeaveRequest request1 = new LeaveRequest("小明", 2);
LeaveRequest request2 = new LeaveRequest("小红", 4);
LeaveRequest request3 = new LeaveRequest("小刚", 6);
LeaveRequest request4 = new LeaveRequest("小何", 10);
personnelHandler.handleRequest(request1);
personnelHandler.handleRequest(request2);
personnelHandler.handleRequest(request3);
personnelHandler.handleRequest(request4);
}
}
运行结果:
人事部负责人批准小明的请假申请,天数为2天
财务部负责人批准小红的请假申请,天数为4天
技术部负责人批准小刚的请假申请,天数为6天
示例二
场景描述:一个人喜欢看动作电影和喜剧电影,他有两个电影分类的账号,为了避免每次登录都要进行选择分类,他希望选择一个账号后能自动显示和该账号对应的电影分类列表。
// 抽象处理者
public abstract class Handler {
private Handler nextHandler;
protected String account;
public Handler(String account) {
this.account = account;
}
// 处理请求
public void handleRequest(String account) {
if (account.equals(this.account)) {
this.display();
} else {
if (nextHandler != null) {
nextHandler.handleRequest(account);
} else {
System.out.println("没有找到该账号的电影分类列表");
}
}
}
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}
public abstract void display();
}
// 具体处理者-动作电影分类列表
public class ActionHandler extends Handler {
public ActionHandler(String account) {
super(account);
}
@Override
public void display() {
System.out.println(this.account + ": 动作电影分类列表");
}
}
// 具体处理者-喜剧电影分类列表
public class ComedyHandler extends Handler {
public ComedyHandler(String account) {
super(account);
}
@Override
public void display() {
System.out.println(this.account + ": 喜剧电影分类列表");
}
}
// 责任链客户端
public class Client {
public static void main(String[] args) {
Handler actionHandler1 = new ActionHandler("账户1");
Handler comedyHandler1 = new ComedyHandler("账户1");
Handler actionHandler2 = new ActionHandler("账户2");
Handler comedyHandler2 = new ComedyHandler("账户2");
actionHandler1.setNextHandler(comedyHandler1);
comedyHandler1.setNextHandler(actionHandler2);
actionHandler2.setNextHandler(comedyHandler2);
actionHandler1.handleRequest("账户1");
actionHandler1.handleRequest("账户2");
actionHandler1.handleRequest("账户3");
}
}
运行结果:
账户1: 动作电影分类列表
账户2: 喜剧电影分类列表
没有找到该账号的电影分类列表
四、总结
责任链模式可以有效地解决请求发送者和接收者之间的耦合关系,使得多个对象都有机会处理同一个请求。在实际应用中,我们可以根据具体需求将责任链设置为不同的长度和顺序,以及不同的处理方式。同时,要注意控制责任链的长度和避免循环调用和死循环的出现,从而保证程序的正常运行和可维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java实现设计模式之责任链模式 - Python技术站