设计模式:职责链模式(Chain Of Responsibility)
定 义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
结构图:
处理请求类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//抽象处理类 abstract class Handler { protected Handler successor; public void SetSuccessor(Handler successor) { this.successor = successor; //设置继任者 } public abstract void HandlerRequest(int request); //处理请求的抽象方法 } //具体处理类1 class ConcreteHandler1 : Handler { public override void HandlerRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); //处理该请求 } else if (successor != null) { successor.HandlerRequest(request); //将请求转移到继任者处理 } } } //具体处理类2 class ConcreteHandler2 : Handler { public override void HandlerRequest(int request) { if (request >= 10 && request < 20) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); //处理该请求 } else if (successor != null) { successor.HandlerRequest(request); //将请求转移到继任者处理 } } } //具体处理类3 class ConcreteHandler3 : Handler { public override void HandlerRequest(int request) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); //处理该请求 } }
客户端调用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.SetSuccessor(h2); h2.SetSuccessor(h3); int[] requests = { 2, 5, 14, 22 }; foreach (int request in requests) { h1.HandlerRequest(request); }
结果:
职责链模式和状态模式对比:
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
从代码中我们可以看出,职责链模式的链式在客户端连接的,也就是说,如果我们请假,请假制度一旦改变,比如说我们不需要班长,或者是先请求老师后直接请求主任或者中间多了一个环节,都是很容易实现的,所以,职责链模式要比状态模式灵活很多。
但是,这时候是不是有人要问,都可以解决If分支过多,是不是职责链模式比状态模式好呢,还是那句话,存在即合理,职责链模式虽然灵活,但是他过于灵活,我们在使用时需要确定下一个对象是谁,在多次设置的时候很容易出问题,所以,这时候用状态模式就比较好,就像我们记录一天的行为,事情已经发生,如果用职责链模式就显得画蛇添足了。
从定义来看,状态模式是一个对象的内在状态发生改变(一个对象,相对比较稳定,处理完一个对象下一个对象的处理一般都已确定),而职责链模式是多个对象之间的改变(多个对象之间的话,就会出现某个对象不存在的现在,就像请假例子中的班长或者老师可能缺勤),这也说明他们两个模式处理的情况不同。
其实,这两个设计模式最大的区别就是状态模式是让各个状态对象自己知道其下一个处理的对象是谁,即在编译时便设定好了的;
而职责链模式中的各个对象并不指定其下一个处理的对象到底是谁,只有在客户端才设定。用我们通俗的编程语言来说,就是
状态模式: 相当于If else if else; 设计路线:各个State类的内部实现(相当于If,else If内的条件) 执行时通过State调用Context方法来执行。 职责链模式: 相当于Swich case 设计路线:客户设定,每个子类(case)的参数是下一个子类(case)。 使用时,向链的第一个子类的执行方法传递参数就可以。
就像对设计模式的总结,有的人采用的是状态模式,从头到尾,提前一定定义好下一个处理的对象是谁,而我采用的是职责链模式,随时都有可能调整链的顺序,这也算是依个人口味均匀添加了吧!!!适合就好!