Gof定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
动机
在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。
理解
责职链这个名字取的很好,就像这个名字反映射出来的意思一样。在我们的生活中,一个员工如果请假,如果请一个下午的假,那么向经理说一下就可以。如果是请二天的假,那么你就得向主管请假,经理没权放你这么长的假。同理向总裁你就可以请到更长的假期。
那么就好像上面这个图一样,经理,主管,总裁都拥有请假的权力,只是拥有的权力大小不一样,他们彼此相链,构成一个链路,当经理没办法决定的假期,由主管决定,当主管没办法决定的假期,由总裁决定。
构成链条,但不是真正的职责链 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
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他会去找在一开始传递给他的上一级的那个。