所以,这么看来这个模式和我们的例子简直是绝配,我们已经做了大部分的工作了,现在剩下的就只是修改审批者,让审批者能链起来
代码重构
修改请假审批基类
最重要的改动,就是修改基类,让对象能链起来,在VacationApprover中添加一个后继节点和一个设置后继节点的方法。同时在基类的审批方法中,完成请求传递,即,如果请假申请超过了当前审批人的能力范围,则转发至后继节点。修改后的类如下
abstract class VacationApprover
{
private VacationApprover nextVacationApprover = null;
public void SetNextVacationApprover(VacationApprover approver)
{
nextVacationApprover = approver;
}
protected VacationApprover(int dayCanHandle)
{
DayCanHandle = dayCanHandle;
}
public int DayCanHandle { get; protected set; }
public void HandleVacationRequest(VacationRequest request)
{
if (request.DayNum <= DayCanHandle)
{
DoHandleVacationRequest(request);
}
else
{
if(nextVacationApprover != null)
{
nextVacationApprover.HandleVacationRequest(request);
}
else
{
Console.WriteLine("Cannot handle this request after all");
}
}
}
protected abstract void DoHandleVacationRequest(VacationRequest request);
}
修改请假审批系统
基类重构结束之后,请假审批系统就可以瘦身了,删除了所有判断逻辑,仅仅在构造函数里面完成链组建的工作,接着一键调用,齐活。
class VacationApproveSystem
{
private VacationApprover teamLeader = new TeamLeader();
private VacationApprover departmentLeader = new DepartmentLeader();
private VacationApprover boss = new Boss();
public VacationApproveSystem()
{
teamLeader.SetNextVacationApprover(departmentLeader);
departmentLeader.SetNextVacationApprover(boss);
}
public void HandleVacationRequest(VacationRequest request)
{
Console.WriteLine("Now handle {0}'s {1} days' vacation request", request.RequesterName, request.DayNum);
teamLeader.HandleVacationRequest(request);
}
}
测试
其他请假审批子类和测试客户端都不需要改动,这次重构工作量非常小,运行代码,一切正常,重构成功。
总结
这就是职责链模式的使用。和状态模式有点像,解决了以下问题:
通过添加子类把一些逻辑判断从调用类(VaccationApproveSystem)移到子类的方式,使得调用类满足迪米特法则 想在职责链上面添加更多节点的时候,只需要添加新类和修改链组装部分的代码,基本满足开闭原则(这里几乎不可能完全满足开闭原则,毕竟有修改就意味着我们肯定会改动VaccationApproveSystem类,只是我们应该尽量的让代码改动量少,以提高控制代码变动的能力)和状态模式一样,它也有子类爆炸的风险。










