我也设计模式——15.Chain of Responsablity
一提到这个模式就会想到“击鼓传花”这个游戏。
这个模式的核心主要是Handler抽象类,几个设计要点:
1.它要保持对自身的一个引用,就是next字段以及相应属性
2.DoHandler()方法是一个递归遍历,直到处理完这个请求
传入的参数字符串s是等待处理的请求,当然,这个参数可以是任意类
3.HandlerRequest()方法要抽象出来,
传入的参数要与DoHandler()方法的参数保持一致
一定要返回bool型,以表示是否处理了这个请求;
来看一个具体的处理类ConcreteHnadler1:体现了能处理就处理的原则。
Client端的调用是很讲究的,要先组链,再使用:
这个模式的核心主要是Handler抽象类,几个设计要点:
1.它要保持对自身的一个引用,就是next字段以及相应属性
2.DoHandler()方法是一个递归遍历,直到处理完这个请求
传入的参数字符串s是等待处理的请求,当然,这个参数可以是任意类
3.HandlerRequest()方法要抽象出来,
传入的参数要与DoHandler()方法的参数保持一致
一定要返回bool型,以表示是否处理了这个请求;
public abstract class Handler
{
private Handler next;
public Handler Next
{
get { return next; }
set { next = value; }
}
public abstract bool HandlerRequest(string s);
public void DoHandler(string s)
{
if (!HandlerRequest(s))
{
if (next != null)
next.DoHandler(s);
else
Console.WriteLine("已经到达尽头,无法对其进行处理!");
}
}
}
{
private Handler next;
public Handler Next
{
get { return next; }
set { next = value; }
}
public abstract bool HandlerRequest(string s);
public void DoHandler(string s)
{
if (!HandlerRequest(s))
{
if (next != null)
next.DoHandler(s);
else
Console.WriteLine("已经到达尽头,无法对其进行处理!");
}
}
}
来看一个具体的处理类ConcreteHnadler1:体现了能处理就处理的原则。
public class ConcreteHnadler1 : Handler
{
public override bool HandlerRequest(string s)
{
if (s == "1")
{
//Do something
return true;
}
return false;
}
}
{
public override bool HandlerRequest(string s)
{
if (s == "1")
{
//Do something
return true;
}
return false;
}
}
Client端的调用是很讲究的,要先组链,再使用:
Handler handler;
ConcreteHnadler1 ch1 = new ConcreteHnadler1();
ConcreteHnadler2 ch2 = new ConcreteHnadler2();
//组链
handler = ch1;
ch1.Next = ch2;
//使用
handler.DoHandler(“3”);
ConcreteHnadler1 ch1 = new ConcreteHnadler1();
ConcreteHnadler2 ch2 = new ConcreteHnadler2();
//组链
handler = ch1;
ch1.Next = ch2;
//使用
handler.DoHandler(“3”);
我尝试着实现基于委托的职责链模式,发现这是有问题的,分析如下:
一旦用detegate链模拟职责链的各个处理类,使用+=来组链而不是Next属性,那么对于委托链而言,返回的永远是最后一个方法的值,因此我不知道处理过程中是谁处理了请求,而后的方法还会继续执行下去,原先的bool返回值失去了作用。就是说,我不能在执行中途停下来,检测每一个方法的bool值——这导致了响应链运转不灵。
现实中,有两个著名案例:
1.MSDN帮助系统,就是基于职责链的:假设光标停在一个系统方法上,按完F1后,先找到最匹配的,逐渐扩大范围,最后找到最一般的
2..NET异常机制:从底层具体异常到高层Exception类层层分析报错
以一个笑话结束这个模式的讨论:
晚上去上英语课,为了好开溜坐到了最后一排,哇,前面坐了好几个漂亮的MM哎,找张纸条,写上“Hi,可以做我的女朋友吗?如果不愿意请向前传”,纸条就一个接一个的传上去了,糟糕,传到第一排的MM把纸条传给老师了,听说是个老处女呀,快跑!