设计模式(13) 职责链模式

行为型模式

行为型模式关注于应用运行过程当中算法的提供和通讯关系的梳理。
相比于建立型模式和结构型模式,行为型模式包含了最多的设计模式种类,包括:算法

  • 职责链模式
  • 模板方法模式
  • 解释器模式
  • 命令模式
  • 迭代器模式
  • 中介者模式
  • 备忘录模式
  • 观察者模式
  • 状态模式
  • 策略模式
  • 访问者模式

职责链模式

职责链模式为了不请求发送者与接收者耦合在一块儿,让多个对象都有可能接收请求,会将这些对象链接成一条链,而且沿着这条链传递请求,直到有对象处理它为止。设计模式

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 Softwareide

在平常生活中,也会遇到相似的具备一系列“工序”的场景,好比用洗衣机洗衣服,须要通过注水、洗涤、漂洗、排水等过程,但做为使用者,咱们并不须要关注这些步骤,须要作的只是把衣服放到洗衣机、加入洗涤剂、等结束后取出而已。性能

职责链模式的使用场景

  • 输入对象须要通过一系列处理,而每一个处理环节也只针对这个对象进行修改,但产出的是同一个对象,好比洗衣服要通过多个步骤,但每一个步骤产出的都是衣服自己。
  • 对象自己要通过哪些处理须要在运行态动态决定,决定的因素可能取决于对象当前的某些属性或外部策略,但为了把输入方和输出方从与每一个具体的处理环节的耦合关系中解脱出来,能够考虑把它们作成一条链,按照每一个节点的后继依次遍历,酌情处理。
  • 须要向多个操做发送处理请求时,能够用链表的形式组织它们。
  • 在对象处理常常发生动态变化的状况下,借助链表来动态维护处理对象。

UML类图:
职责链模式 UML类图this

代码示例
假设商品的价格分红内部认购价、折扣价、平价,以及邮购价格,用职责链模式来进行价格的计算:设计

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

}

在实际应用中,组装职责链的过程能够交给建立型模式,或者从配置读取。code

职责链模式的特色

优点
从上面的示例能够发现这种模式的一些优点:对象

  • 下降了请求发送者和接收者之间的耦合,请求发送者只须要拿到调用链的头部,就能够触发链式处理。
  • 能够动态地改变链内节点的次序,也能够方便地动态增长、删除节点,并即刻生效。

缺点blog

  • 不能保证请求必定被接收。
  • 系统性能将受到必定影响,并且在进行代码调试时不太方便。
  • 若是调用链组装不合理,可能会形成循环调用。

参考书籍: 王翔著 《设计模式——基于C#的工程化实现及扩展》

相关文章
相关标签/搜索