职责链模式
2012-08-24 11:42 Mike.Jiang 阅读(601) 评论(0) 编辑 收藏 举报1概述
当一个请求,有多个处理对象时,如果硬编码指定某个由某个对象来处理,需要采用ifelse的结构,从而产生了代码的耦合,如果要添加新的请求处理对象或调整请求处理的次序,必然会修改同一个方法,违背开闭原则。
2 GOF中的定义
意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构图:
适用性:
1>有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2>你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3>解耦ifelse,将处理对象组织一个链并希望处理的次序由客户端来定义;
3项目中的例子
在简单的审批处理中,经理与总经理有着不同的处理级别。比如,在请假审批中,经理可以批准3天的,而当要请假5天时需要总经理审批。在这里,我们定义请假3天的级别为3,请假5天的级别为5。
4紧耦合的实现
代码:
public class Manager { public void HandelRequest(int levelDays) { if (levelDays <= 3) { Console.WriteLine("经理处理请假"); } else { Console.WriteLine("总经理处理请假"); } } } static void Main(string[] args) { Manager manager = new Manager(); manager.HandelRequest(4); Console.Read(); }
说明:在这里,不同的请求处理对象耦合在ifelse分支中,当新修改、添加新的请求处理对象,或要调整请求处理次序时,都要修改Manager的HandelRequest方法,很明显违背了开闭、单一职责原则。
5松耦合的实现
代码:
/// <summary> /// 处理请求对象的基类 /// </summary> public abstract class Manager { /// <summary> /// 维护一个指向下一个请求处理对象的引用 /// </summary> protected Manager nextHander; public void SetNextHander(Manager manager) { this.nextHander = manager; } /// <summary> /// 请求处理方法,由子类实现 /// </summary> /// <param name="reqLevel"></param> public abstract void HandelRequest(int reqLevel); } /// <summary> /// 经理 /// </summary> public class NomalManager:Manager { public override void HandelRequest(int reqLevel) { if (reqLevel <= 3) { Console.WriteLine("{0}:同意请假", this.GetType().Name); } else if (nextHander != null) { nextHander.HandelRequest(reqLevel); } } } /// <summary> /// 总经理 /// </summary> public class GeneralManager:Manager { public override void HandelRequest(int reqLevel) { if (reqLevel > 3) { Console.WriteLine("{0}:同意请假", this.GetType().Name); } else if (nextHander != null) { nextHander.HandelRequest(reqLevel); } } } static void Main(string[] args) { Manager normalManager = new NomalManager(); Manager generalManager = new GeneralManager(); normalManager.SetNextHander(generalManager); normalManager.HandelRequest(3); normalManager.HandelRequest(4); Console.Read(); }
说明:在这里,将不同的请求处理行为抽象成类,然后将这些类构成一个链式结构(此时链的前后关系由客户端定义,提高了灵活性)。当有请求时,只需要调用处理链中的第一个就可以完成各种请求,不需要将某个请求与具体的处理对象关联了。
6总结
职责链模式解决的是将ifelse解耦,但它与策略模式不同,它将行为对象组织成一个链式结构来处理请求,一步步向后处理。很明显这样做会浪费一些性能,如加载了一些不会用的到类(因为只有一个对对象才会处理某个请求),另外如果请求只有最后一个才能处理,要经过之前的层层判断才会至最后一个。但是在一些业务系统中,这样的做会更加容易理解与维护。