『设计模式』职责链模式(Chain of Responsibility) 可怜的加薪、请假之路
23 种设计模式+额外常用设计模式汇总 (持续更新)
问题抽象
客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的。
对于客户端而言,无所谓谁来处理,反正有对象处理就可以了。而且在上述处理中,还希望处理流程是可以灵活变动的,而处理请求的对象需要能方便地修改或者是被替换掉,以适应新的业务功能的需要。
职责链模式
十多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连城一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
模式结构
处理过程
ConcreteHandler 将自己的后继对象(向下传递消息的对象)记录在自己的后继表中,当一个请求到来时,ConcreteHandler 会先检查看自己有没有匹配的处理程序,如果有就自己处理,否则传递给它的后继。
职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
优点
请求者和接收者松散耦合
动态组合职责
缺点
产生很多细粒度对象
不一定能被处理:需要提供默认处理
本质
分离职责,动态组合,如果学习过状态模式,可以理解为可以动态设置转移方向的状态模式。
状态模式是一个对象的内在状态发生改变,一个对象,相对比较稳定,处理完一个对象下一个对象的处理一般都已确定
职责链模式过于灵话,在客户端使用时,需要环境去确定下一个对象是谁,一些列的 set 操作…职责链模式是多个对象之间的改变,就会出现某个对象不存在的情景。
实现:
我们使用百度百科的一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Request { private string requestType; public String getrequestType (){ return requestType; } public void setrequestType (string requestType){ this.requestType=requestType; }
private string requestContent;
public String getrequestContent (){ return requestContent; } public void setrequestContent (string requestContent){ this.requestContent=requestContent; }
private int number; public int Number { get { return number; } set { number = value; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| abstract public class Manager { protected string name; protected Manager superior; public Manager(string name) { this.name = name; }
public void SetSuperior(Manager superior) { this.superior = superior; } abstract public void RequestApplications(Request request); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
public class CommonManager extends Manager { public CommonManager(string name) { super(name);}
publicvoid RequestApplications(Request request) { if (request.RequestType == "请假" && request.Number <= 2) { Console.WriteLine("{0}:{1}数量{2}被批准", name, request.RequestContent, request.Number); } else { if (superior != null) superior.RequestApplications(request); } } }
public class Majordomo extends Manager { public Majordomo(string name) { super(name);}
public void RequestApplications(Request request) { if (request.RequestType == "请假" && request.Number <= 5) { System.out.println( name+":"+ request.RequestContent+"数量"+request.Number+"被批准"); } else { if (superior != null) superior.RequestApplications(request); } } }
public class GeneralManager extends Manager { public GeneralManager(string name) {super(name); }
publicvoid RequestApplications(Request request) { if (request.RequestType == "请假") { System.out.println( name+":"+ request.RequestContent+"数量"+request.Number+"被批准"); } else if (request.RequestType == "加薪"&&request.Number<=500) { System.out.println( name+":"+ request.RequestContent+"数量"+request.Number+"被批准"); } else if (request.RequestType == "加薪" && request.Number > 500) { System.out.println( name+":"+ request.RequestContent+"数量"+request.Number+"在说吧"); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Client { public static void Main(string[] args) { CommonManager jinli = new CommonManager("张三"); Majordomo zongjian = new Majordomo("李四"); GeneralManager zongjinli = new GeneralManager("王五"); jinli.SetSuperior(zongjian); zongjian.SetSuperior(zongjinli);
Request request = new Request(); request.RequestType = "请假"; request.RequestContent = "XX请假"; request.Number = 1; jinli.RequestApplications(request);
Request request2 = new Request(); request.RequestType = "加薪"; request.RequestContent = "XX加薪"; request.Number = 500; jinli.RequestApplications(request);
} }
|