定义
责任链模式是一种以分层过程"处理"事件的模式,这么说可能有点模糊,
举个例子:假设我有一家餐厅,餐厅里有"学徒,厨师,厨师长"三种角色,顾客来餐厅吃饭,先将需要做的菜交给学徒,学徒不能完成制作过程复杂的菜品,只能往下一级及厨师传递做菜信息,厨师也不能完成特别高难度的菜品,当菜品难度过高只能找厨师长完成。
当角色的能力完成不了事件时,会传递给下一下,这种场景用代码实现出来就叫责任链模式。
硬编码实现
public void Cook(Meal meal){
Console.WriteLine("顾客点餐");
if(meal.Difficulty <= 3)
Console.WriteLine("学徒完成菜品");
else if(meal.Difficulty > 3 && meal.Difficulty <= 5)
Console.WriteLine("厨师完成菜品");
else
Console.WriteLine("厨师长完成菜品");
}
以上代码也能实现之前描述的场景,但会有几个问题
- 如果在添加新的角色进来,会导致IF/ELSE更加混乱,阅读性不高
- 再加入新的条件判断时,会让IF/ELSE更加混乱,并且也会导致每个角色的职责不清晰
使用责任链模式编码
我们将之前的场景使用责任链模式重写,将职责封装在"学徒,厨师,厨师长"三种角色中。
定义三种角色,并将职责分配到角色中
/// <summary>
/// 处理人的抽象
/// </summary>
public abstract class Handler
{
public Handler NextHandler { get; private set; }
public string Name { get; private set; }
public Handler(string name, Handler nextHandler = null)
{
this.Name = name;
if (nextHandler != null)
this.NextHandler = nextHandler;
}
public abstract void Cook(Meal meal);
}
/// <summary>
/// 学徒
/// </summary>
public class Apprentice : Handler
{
public Apprentice(string name, Cooker handler) : base(name, handler)
{
}
public override void Cook(Meal meal)
{
if (meal.Difficulty > 3)
this.NextHandler.Cook(meal);
else
Console.WriteLine($"学徒{this.Name}制作{meal.Name}成功");
}
}
/// <summary>
/// 厨师
/// </summary>
public class Cooker : Handler
{
public Cooker(string name, CookerMaster handler) : base(name, handler)
{
}
public override void Cook(Meal meal)
{
if (meal.Difficulty > 5)
this.NextHandler.Cook(meal);
else
Console.WriteLine($"厨师{this.Name}制作{meal.Name});
}
}
}
/// <summary>
/// 厨师长
/// </summary>
public class CookerMaster : Handler
{
public CookerMaster(string name) : base(name)
{
}
public override void Cook(Meal meal)
{
Console.WriteLine($"厨师长{this.Name}完成了{meal.Name}这道菜");
}
}
通过指定上级的方式,创建出责任链。
CookerMaster master = new CookerMaster("小明");
Cooker cooker = new Cooker("小刚", master);
Apprentice apprentice = new Apprentice("小红", cooker);
顾客点餐,开始制作菜品
var aoZhouLongXia = new Meal("澳洲龙虾", 7);
apprentice.Cook(aoZhouLongXia);
优点与缺点
优点:
- 将职责与角色绑定在一起,更加符合面向对象的设计
- 上述场景中"学徒"总是第一个来处理事件,不需要在根据条件去寻找谁应该来处理事件
- 并且扩展性提高了,加入新的角色更加方便
缺点
- 当责任链过长时,可能会导致性能问题