责任链模式用于在软件设计中实现松散耦合,其中来自客户端的请求被传递到对象链以处理它们。然后链中的对象将自己决定谁将处理请求以及是否需要将请求发送到链中的下一个对象。
降低耦合度:请求发送者和接收者都没有对方的明确信息,而是通过抽象处理器来链接。实现了请求的发送者和处理者之间的解耦。
灵活性:可以动态地增加或删除处理器,方便扩展和维护。
易于实现: 在责任链模式中,每个具体的处理器只需要实现自己的功能即可,不需要知道整个请求链的存在,这样更加容易实现其功能。
不能保证请求一定会被处理:在责任链模式中,由于请求的处理是由多个对象负责的,所以不能保证请求一定会被处理,存在漏洞导致请求无响应的风险。
性能问题:在应用责任链模式时需要控制链中的处理器数量,过多的处理器会导致处理时间增加,从而影响系统性能。
调试困难:责任链模式中的处理器是动态组合的,处理逻辑较为复杂,因此需要进行详细的测试和调试。
责任链模式 与 状态模式 比较 :
在 责任链模式 中 , 并 不指定 下一个处理的 请求对象 是哪个 ; 责任链 中 链条顺序 可以 任意组合排序 ;但是在 状态模式 中 , 需要让 每个 状态 知道下一个需要处理的状态是谁 。
设置一个简单的案例来测试该设计模式。比如请假的条件是今年上班的天数以及职位来判断该员工是否可以请假,为难一下打工人。
请假条件
@Data @AllArgsConstructor @NoArgsConstructor public class LeaveCondition { private Integer workDay; private String role; }
天数判定
public class LeaveDayService extends ProcessorChain { @Override public void doHandle(LeaveCondition leaveCondition) { if (leaveCondition.getWorkDay() < 60) { System.out.println("ur day not enough"); if (chain!=null){ chain.doHandle(leaveCondition); } }else { System.out.println("ur day enough"); return; } } }
职位判定?
public class LeaveRoleService extends ProcessorChain{ public final static String ROLE="USER"; @Override public void doHandle(LeaveCondition leaveCondition) { if (!ROLE.equals(leaveCondition.getRole())){ System.out.println("ur role don't have permission"); if (chain!=null){ chain.doHandle(leaveCondition); } return; }else { System.out.println("ur role have permission"); return; } } }
关键代码进行到下一个节点
public abstract class ProcessorChain{ protected ProcessorChain chain; public void next(ProcessorChain handler){ this.chain = handler; } public abstract void doHandle(LeaveCondition leaveCondition); }
?
Test
@SpringBootTest class DemoApplicationTests { @Test void contextLoads() { LeaveCondition leaveCondition=new LeaveCondition(); leaveCondition.setRole("aaaaa"); leaveCondition.setWorkDay(50); ProcessorChain leaveDayService = new LeaveDayService(); ProcessorChain leaveRoleService = new LeaveRoleService(); leaveDayService.next(leaveRoleService); leaveDayService.doHandle(leaveCondition); } }
剩下的可以自己进行测试,这只是一个简单的学习测试案例
在节点里面做业务判定时,注意找个代码
if (chain!=null){ chain.doHandle(leaveCondition); }
他可以避免在最后一个节点继续往下走报空指针异常?