TOP

设计模式(13) 职责链模式(一)
2020-07-30 06:08:38 】 浏览:23次 本网站的内容取自网络,仅供学习参考之用,绝无侵犯任何人知识产权之意。如有侵犯请您及时与本人取得联系,万分感谢。
Tags:设计模式 职责 模式

行为型模式

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

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

职责链模式

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

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类图:
职责链模式 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

}

在实际应用中,组装职责链

请关注公众号获取更多资料


设计模式(13) 职责链模式(一) https://www.cppentry.com/bencandy.php?fid=97&id=296384

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇你必须了解的「架构」小历史 下一篇微服务系列之Nacos配置中心之一:..

评论

验 证 码:
表  情:
内  容: