动机(Motivate):
在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合。
如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。
意图(Intent):
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
适用性:
1.有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2.你想在不明确接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态指定。
职责链模式与状态模式很相似,状态模式将各个状态的切换写在各自的内部,逐级变化,而职责链模式将各个状态的切换写在外部,由用户指定
#region 构建抽象处理者 public abstract class Approver { protected Approver _approver;//保证同一个实例下,设置交付SetSuccessor都为同一个Approver对象 public void SetSuccessor(Approver approver) { _approver = approver; } public abstract void ProcessRequest(Purchase purchase); } #endregion
#region 具体批准者 //主任 class Director : Approver { public override void ProcessRequest(Purchase purchase) { if (purchase.Amount < 10000.0) { Console.WriteLine("{0} Handle{1}", this.GetType().Name, purchase.Number); } else if (_approver != null) { _approver.ProcessRequest(purchase); } } } //副总裁 class VicePresident : Approver { public override void ProcessRequest(Purchase purchase) { if (purchase.Amount < 25000.0) { Console.WriteLine("{0} Handle{1}", this.GetType().Name, purchase.Number); } else if (_approver != null) { _approver.ProcessRequest(purchase); } } } //总裁 class President : Approver { public override void ProcessRequest(Purchase purchase) { if (purchase.Amount < 100000.0) { Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number); } else { Console.WriteLine("Request! {0} requires an executive meeting!", purchase.Number); } } } #endregion
#region 唯一的购买者 public class Purchase { private int _number; private double _amount; private string _purpose; public Purchase(int number, double amount, string purpose) { _number = number; _amount = amount; _purpose = purpose; } public int Number { get { return _number; } set { _number = value; } } public double Amount { get { return _amount; } set { _amount = value; } } public string Purpose { get { return _purpose; } set { _purpose = value; } } } #endregion
static void Main(string[] args) { Purchase purchase = new 职责链模式.Purchase(001,24000.0,"存款"); Director director = new 职责链模式.Director(); VicePresident vicepresident = new 职责链模式.VicePresident(); President president = new 职责链模式.President(); director.SetSuccessor(vicepresident);//主任无法处理交给副总裁 vicepresident.SetSuccessor(president);//副总裁无法处理交给总裁 director.ProcessRequest(purchase); Console.WriteLine("***"); director.SetSuccessor(president);//或者主任无法处理直接交给总裁,这个可以灵活选择 director.ProcessRequest(purchase); Console.ReadKey(); }
状态模式让对象最终知道它属于哪个状态,策略模式让对象找到属于自己的本身情况对应类别该执行的方法。