zoukankan      html  css  js  c++  java
  • c#职责链模式

    何为职责链

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

    图如下:

    chain

    职责链模式应用之请假管理

    请假这个事情,相信每个人都不陌生。

    我们公司是个相对很宽松的公司。

    在公司里,如果你的请假时间小于0.5天,那么只需要向项目经理打声招呼就OK了。

    如果超过了0.5天,但是还小于2天,那么就要去找人事部处理,当然,这就要扣工资了。

    如果超过了2天,你就需要去找总经理了,工资当然也玩完了。

    那么,对于我们来说,这个流程就是这样的。

    image

    也就是这样一个过程,你需要和你的直接上级——项目经理去打交道,最终可能是项目经理给你回邮件,可能是人事部给你回邮件,也可能是总经理给你回邮件。内部的过程其实应该是个黑盒子,你并不知道内部的消息是如何处理的。你需要找到的,只是你想要第一个交付的对象而已。

    无标题

    那么我们的代码应该是这样的。

    首先我们要写一个请求的类。

    class Request
    {
        private int day;
        private string reason;
        public int Day
        {
            get { return day; }
            set { day = value; }
        }
        public string Reason
        {
            get { return reason; }
            set { reason = value; }
        }
        public Request(int day, string reason)
        {
            this.day = day;
            this.reason = reason;
        }
    }
    接下来看下请求相应者,他们有两个核心方法,一个是相应操作,一个是选择继任者。
    abstract class Boss
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private Boss successor;
        public Boss Successor
        {
            get { return successor; }
            set { successor = value; }
        }
        public Boss(string name)
        {
            this.name = name;
        }
        public abstract bool PassRequest(Request request);
    }
    class PM:Boss
    {
        public PM(string name)
            : base(name)
        { }
        public override bool PassRequest(Request request)
        {
            int day = request.Day;
            string reason = request.Reason;
            if (day <= 0.5)
            {
                return true;
            }
            return Successor.PassRequest(request);
        }
    }
    class HR:Boss
    {
        public HR(string name)
            : base(name)
        { }
        public override bool PassRequest(Request request)
        {
            int day = request.Day;
            string reason = request.Reason;
            if (day > 0.5&&day<=2)
            {
                return true;
            }
            return Successor.PassRequest(request);
        }
    }
    class Manager : Boss
    {
        public Manager(string name)
            : base(name)
        { }
        public override bool PassRequest(Request request)
        {
            int day = request.Day;
            string reason = request.Reason;
            if (reason.Equals("正当理由"))
            {
                return true;
            }
            return false;
        }
    }

    那么我们调用的时候就很简单了!

    static void Main(string[] args)
    {
        Request request = new Request(3, "非正当理由");
        Boss pm = new PM("pm");
        Boss hr = new HR("hr");
        Boss manager = new Manager("manager");
        pm.Successor = hr;
        hr.Successor = manager;
        bool pass = pm.PassRequest(request);
        Console.Write(pass);
    }

    灵活在哪

    让我们来看下职责链究竟灵活在哪?

    1. 改变内部的传递规则。

    无标题

    在内部,项目经理完全可以跳过人事部到那一关直接找到总经理。

    每个人都可以去动态地指定他的继任者。

    2. 可以从职责链任何一关开始。

    如果项目经理不在,那么完全可以写这样的代码:

    static void Main(string[] args)
    {
        Request request = new Request(3, "非正当理由");
        Boss pm = new PM("pm");
        Boss hr = new HR("hr");
        Boss manager = new Manager("manager");
        pm.Successor = hr;
        hr.Successor = manager;
        //bool pass = pm.PassRequest(request);
        bool pass = hr.PassRequest(request);
        Console.Write(pass);
    }

     职责链的缺点

    让我们继续回到上面的例子,我们发现,其实当请假时间超过2天的时候,PM和HR其实没有做任何的事情,而只是做了一个传递工作。

    而传递工作之后,他们就成了垃圾对象。

    也就是说,他们在实际的处理中,并没有发挥任何的作用。

    那么当这个链结构比较长,比较复杂的话,会产生很多的内存垃圾对象。

    这也就是职责链的最大缺点之所在。

  • 相关阅读:
    linux内核中GNU C和标准C的区别
    linux内核中GNU C和标准C的区别
    Getting start with dbus in systemd (02)
    Getting start with dbus in systemd (01)
    Getting start with dbus in systemd (03)
    物理内存相关的三个数据结构
    数据类型对应字节数(32位,64位 int 占字节数)
    Linux kernel 内存
    共模电感的原理以及使用情况
    [原创]DC-DC输出端加电压会烧毁
  • 原文地址:https://www.cnblogs.com/HKKD/p/7115020.html
Copyright © 2011-2022 走看看