行为型模式关注于应用运行过程中算法的提供和通信关系的梳理。
相比于创建型模式和结构型模式,行为型模式包含了最多的设计模式种类,包括:
职责链模式为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,会将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
GOF对外观模式的描述为:
Avoid coupling the sender of a request to its receiver by giving morethan one object a chance to handle the request. Chain the receivingobjects and pass the request along the chain until an object handles it.
— Design Patterns : Elements of Reusable Object-Oriented Software
在日常生活中,也会遇到类似的具有一系列“工序”的场景,比如用洗衣机洗衣服,需要经过注水、洗涤、漂洗、排水等过程,但作为使用者,我们并不需要关注这些步骤,需要做的只是把衣服放到洗衣机、加入洗涤剂、等结束后取出而已。
UML类图:
代码示例
假设商品的价格分成内部认购价、折扣价、平价,以及邮购价格,用职责链模式来进行价格的计算:
public enum PurchaseType
{
Internal, //内部认购价格
Discount, //折扣价
Regular, //平价
Mail //邮购价
}
//请求对象
public class Request
{
public double Price { get; set; }
public PurchaseType Type { get; set; }
public Request(double price, PurchaseType type)
{
this.Price = price;
this.Type = type;
}
}
//抽象的操作对象
public interface IHandler
{
void HandleRequest(Request request);
IHandler Next { get; set; }
PurchaseType Type { get; set; }
}
public abstract class HandlerBase : IHandler
{
public IHandler Successor { get; set; }
public PurchaseType Type { get; set; }
public HandlerBase(PurchaseType type, IHandler successor)
{
this.Type = type;
this.Successor = successor;
}
public HandlerBase(PurchaseType type) : this(type, null) { }
//需要具体IHandler类型处理的内容
public abstract void Process(Request request);
//在当前结点处理,还是传递给下一个结点
public virtual void HandleRequest(Request request)
{
if (request == null) return;
if (request.Type == Type)
{
Process(request);
}
else if (Successor != null)
{
Successor.HandleRequest(request);
}
}
public class InternalHandler : HandlerBase
{
public InternalHandler() : base(PurchaseType.Internal) { }
public override void Process(Request request)
{
request.Price *= 0.6;
}
}
public class MailHandler : HandlerBase
{
public MailHandler() : base(PurchaseType.Mail) { }
public override void Process(Request request)
{
request.Price *= 1.3;
}
}
public class DiscountHandler : HandlerBase
{
public DiscountHandler() : base(PurchaseType.Discount) { }
public override void Process(Request request)
{
request.Price *= 0.9;
}
}
public class RegularHandler : HandlerBase
{
public RegularHandler() : base(PurchaseType.Regular) { }
public override void Process(Request request) { }
}
}
组装职责链并调用
static void Main(string[] args)
{
IHandler handler1 = new InternalHandler();
IHandler handler2 = new DiscountHandler();
IHandler handler3 = new MailHandler();
IHandler handler4 = new RegularHandler();
handler1.Next = handler3;
handler3.Next = handler2;
handler2.Next = handler4;
IHandler head = handler1;
Request request = new Request(20, PurchaseType.Mail);
head.HandleRequest(request);
Console.Write(request.Price); //26
//将MailHandler短路
handler1.Next = handler1.Next.Next;
request = new Request(20, PurchaseType.Mail);
head.HandleRequest(request);
Console.Write(request.Price); //20
}
在实际应用中,组装职责链的过程可以交给创建型模式,或者从配置读取。
优势
从上面的示例可以发现这种模式的一些优势:
缺点
参考书籍:
王翔著 《设计模式——基于C#的工程化实现及扩展》
原文:https://www.cnblogs.com/zhixin9001/p/13399979.html