举个生活中的例子,比如你要请假,请假是时间比较长(十个月),你去找Leader组长,组长一看假条迷惑的说,你要去生孩子吗?这个你得去问项目经理。然后你又转战项目经理那里,项目经理看了说,你是十月请假看国庆典礼那,还是请十个月假回家休养。你肯定得告诉项目经理你要请十个月假。项目经理皱皱眉头说,这个我说了没用,你还是去问老总吧。当你把假条放到老总面前的时候,老总说了句:回去吧,你不用来了。到此责任链执行完毕。当然如果你请1天假的话可能在Leader那里处理就结束了,项目经理和老总你是没有机会看到的。
UML图:
可以看出有所有的责任都继承与同一个接口,接口包括出来方法和下一步责任的流向。责任之间没有耦合,你可以调整任意的责任顺序,比如请求的顺序也可以是老总->项目经理->组长,虽然这样的责任链应该不会产生,但是理论上是可以实现的。
先贴出我们责任链的接口:
public abstract class Handle
{
Handle _handle;
public Handle HandleValue
{
set { _handle = value; }
get { return _handle; }
}
public abstract string RequestHandle(int level);
}
其中有两个重点,一个就是HandleValue属性,可以用来指定下一个责任。RequestHandle方法处理,本例中处理的是int变量,当然你可以搞些更复杂的对象,比如UserInfo什么的。下面是具体的责任类的实现:
public class LowLevel : Handle
{
public override string RequestHandle(int level)
{
if (level <= 8)
{
return "LowLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class MidLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 8 && level <= 16)
{
return "MidLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class HighLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 16 && level <= 25)
{
return "HighLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class OutOfLevel : Handle
{
public override string RequestHandle(int level)
{
return "OutOfLevel";
}
}
注:应该在所有处理完成后加入最终处理方法,比如本例中的OutOfLevel。
测试代码:
DotaPatternLibrary.ChainOfResponsibility.Handle lObj = new DotaPatternLibrary.ChainOfResponsibility.LowLevel();
DotaPatternLibrary.ChainOfResponsibility.Handle mObj = new DotaPatternLibrary.ChainOfResponsibility.MidLevel();
DotaPatternLibrary.ChainOfResponsibility.Handle hObj = new DotaPatternLibrary.ChainOfResponsibility.HighLevel();
DotaPatternLibrary.ChainOfResponsibility.Handle oObj = new DotaPatternLibrary.ChainOfResponsibility.OutOfLevel();
lObj.HandleValue = mObj;
mObj.HandleValue = hObj;
hObj.HandleValue = oObj;
LandpyForm.Form.OutputResult(lObj.RequestHandle(15));
完整代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DotaPatternLibrary.ChainOfResponsibility
{
public abstract class Handle
{
Handle _handle;
public Handle HandleValue
{
set { _handle = value; }
get { return _handle; }
}
public abstract string RequestHandle(int level);
}
public class LowLevel : Handle
{
public override string RequestHandle(int level)
{
if (level <= 8)
{
return "LowLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class MidLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 8 && level <= 16)
{
return "MidLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class HighLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 16 && level <= 25)
{
return "HighLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class OutOfLevel : Handle
{
public override string RequestHandle(int level)
{
return "OutOfLevel";
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DotaPatternLibrary.ChainOfResponsibility
{
public abstract class Handle
{
Handle _handle;
public Handle HandleValue
{
set { _handle = value; }
get { return _handle; }
}
public abstract string RequestHandle(int level);
}
public class LowLevel : Handle
{
public override string RequestHandle(int level)
{
if (level <= 8)
{
return "LowLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class MidLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 8 && level <= 16)
{
return "MidLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class HighLevel : Handle
{
public override string RequestHandle(int level)
{
if (level > 16 && level <= 25)
{
return "HighLevel";
}
else
{
return HandleValue.RequestHandle(level);
}
}
}
public class OutOfLevel : Handle
{
public override string RequestHandle(int level)
{
return "OutOfLevel";
}
}
}