职责链模式
职责链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
我们先来看一下职责链模式的结构图:
首先职责链模式会定义一个所有处理请求的对象都要继承实现的抽象类,这样就有利于随时切换新的实现。其次每个处理请求对象只实现业务流程中的一步业务处理,这样使其变得简单。最后职责链模式会动态地来组合这些处理请求的对象,把它们按照流程组合起来,并要求它们依次调用,这样就动态地实现了流程。
这样一来,如果流程发生了变化,只要重新组合就可以了。如果某个处理业务功能发生了变化,一个方案是修改处理对应的处理对象。另一个是直接提供新的实现,然后在组合流程的时候,用新的实现替换掉旧的实现就可以了。
我们以一个实际例子:员工向领导请假 员工申请——>部门经理(请假天数小于3天)——>总监(请假天数小于5天)——>总经理 来实现相应代码:
public abstract class Handler { protected Handler successor=null; public Handler(Handler successor) { //设置下一个处理请求的对象 successor=successor; } //每个处理对象的处理逻辑 public abstract void handleRequest(string user,int days) }
public class DeptManager:Handler { public string handleRequest(string user,int days) { if(days<3) { //请假相关代码逻辑 } else { //交给下一个处理对象处理 if(successor!=null) { successor.handleRequest(string user,int days); } } } }
public class GeneralManager:Handler { public string handleRequest(string user,int days) { if(days<5) { //请假相关代码逻辑 } else { //交给下一个处理对象处理 if(successor!=null) { successor.handleRequest(string user,int days); } } } }
public class TopManager:Handler { public string handleRequest(string user,int days) { if(days>=5) { //请假相关代码逻辑 } else { //如果还有下一级处理对象 if(successor!=null) { successor.handleRequest(string user,int days); } } } }
最后我们来看一下客户端对职责链的组合:
public class Client { public static void Main(string[] args) { string userName="克里斯·保罗"; int days=20; //构造职责链 TopManager tm=new TopManager(null); GeneralManager gm = new GeneralManager(tm); DeptManager dm=new DeptManager(gm); //发出请求 dm.handleRequest(userName,days); } }
客户端发出一个请求,有多个对象都有机会来处理这一个请求,但是客户端不知道究竟是谁会来处理它的请求。
职责链是怎么构建的呢?实现方式是五花八门的:
可以实现在客户端提交请求前组合链。也就是在使用的时候动态组合链,成为外部链,就像上面的例子。
也可以在Handler里面实现链的组合,算是内部链的一种。
当然还有一种就是在各个职责对象中,由各个职责对象自行决定后续处理对象。这种实现方式要求每个职责对象除了进行业务处理外,还必须了解整个行业的业务流程。
职责链模式的本质:分离职责,动态组合。
开发中很强调面向接口编程,因此接口应该相对保持稳定,接口一改,需要修改的地方就太多了,频繁修改接口绝对不是个好办法。