设计模式- 职责链模式
Gof定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
动机
在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。
理解
责职链这个名字取的很好,就像这个名字反映射出来的意思一样。在我们的生活中,一个员工如果请假,如果请一个下午的假,那么向经理说一下就可以。如果是请二天的假,那么你就得向主管请假,经理没权放你这么长的假。同理向总裁你就可以请到更长的假期。
那么就好像上面这个图一样,经理,主管,总裁都拥有请假的权力,只是拥有的权力大小不一样,他们彼此相链,构成一个链路,当经理没办法决定的假期,由主管决定,当主管没办法决定的假期,由总裁决定。
构成链条,但不是真正的职责链 CODE
View Code
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string str = "大家好,<br/>S真TMD是SB"; msgProcessor processor = new msgProcessor(); string result = processor.process(str); Console.WriteLine(result); Console.ReadLine(); } } class msgProcessor { Filter[] filters = { new HTMLFilter(), new SessionFilter() }; public string process(string str) { string r = str; foreach (Filter f in filters) { r = f.doFilter(r); } return r; } } interface Filter { string doFilter(string str); } class HTMLFilter : Filter { public string doFilter(string str) { string result = str.Replace("<", "[").Replace(">", "]"); return result; } } class SessionFilter : Filter { public string doFilter(string str) { string result = str.Replace("TMD", "***").Replace("SB", "**"); return result; } } }
构成链条,但依然不是真正的职责链 进一步写法 CODE
View Code
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string str = "大家好,<br/>S真TMD是SB... :)...."; FilterChain fc = new FilterChain(); fc.addFilter(new HTMLFilter()).addFilter(new SessionFilter()); FilterChain fc2 = new FilterChain(); fc2.addFilter(new FaceFilter()); //有意思的一步 fc.addFilter(fc2); msgProcessor processor = new msgProcessor(fc); string result = processor.process(str); Console.WriteLine(result); Console.ReadLine(); } } class msgProcessor { FilterChain fc; public msgProcessor(FilterChain fc) { this.fc = fc; } public string process(string str) { return fc.doFilter(str); } } //由于FilterChain实现了Filter的接口,所以addFilter(Filter f)里面可以传递一个FilterChain class FilterChain : Filter { List<Filter> filters = new List<Filter>(); public FilterChain addFilter(Filter f) { filters.Add(f); return this; } public string doFilter(string str) { string r = str; foreach (Filter f in filters) { r = f.doFilter(r); } return r; } } interface Filter { string doFilter(string str); } class HTMLFilter : Filter { public string doFilter(string str) { string result = str.Replace("<", "[").Replace(">", "]"); return result; } } class SessionFilter : Filter { public string doFilter(string str) { string result = str.Replace("TMD", "***").Replace("SB", "**"); return result; } } class FaceFilter : Filter { public string doFilter(string str) { string result = str.Replace(":)", "^V^"); return result; } } }
真正的职责链模式 大话设计模式 简化版 CODE
using System; class Program { static void Main(string[] args) { //初始化 CommonMannger cm = new CommonMannger(); MajordomoManger mm = new MajordomoManger(); GeneralManager gm = new GeneralManager(); //再职责链接起来 cm.SetSuperiro(mm); mm.SetSuperiro(gm); //设计请假天数 Request request = new Request(); request.Number = 30; //开始请假,30天,明显是最后交到了总经理手上 cm.RequestApplications(request); Console.ReadLine(); } class Request { //申请天数 private int number; public int Number { get { return number; } set { number = value; } } } abstract class Manager { protected Manager superior; public void SetSuperiro(Manager superior) { this.superior = superior; } abstract public void RequestApplications(Request request); } //经理 class CommonMannger : Manager { public override void RequestApplications(Request request) { if (request.Number <= 2) { Console.WriteLine("经理批准 两天以下假请申请"); } else { if (superior != null) superior.RequestApplications(request); } } } //总监 class MajordomoManger : Manager { public override void RequestApplications(Request request) { if (request.Number <= 5) { Console.WriteLine("总监批准 五天以下假请申请"); } else { if (superior != null) superior.RequestApplications(request); } } } //总经理 class GeneralManager : Manager { public override void RequestApplications(Request request) { if (request.Number <= 100) { Console.WriteLine("总经理批准 一百天以下假请申请"); } else { Console.WriteLine("你还是直接走人吧!"); } } } }
由于其他职责都是从 Manager 继承,所以都有SetSuperiro方法。
假设去找经理申请,可是经理没有权力的时候,这时候由于有了SetSuperiro他会去找在一开始传递给他的上一级的那个。