设计模式- 职责链模式

Gof定义

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

动机

  在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。

理解

  责职链这个名字取的很好,就像这个名字反映射出来的意思一样。在我们的生活中,一个员工如果请假,如果请一个下午的假,那么向经理说一下就可以。如果是请二天的假,那么你就得向主管请假,经理没权放你这么长的假。同理向总裁你就可以请到更长的假期。

  那么就好像上面这个图一样,经理,主管,总裁都拥有请假的权力,只是拥有的权力大小不一样,他们彼此相链,构成一个链路,当经理没办法决定的假期,由主管决定,当主管没办法决定的假期,由总裁决定。

 

构成链条,但不是真正的职责链 CODE

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "大家好,<br/>S真TMD是SB";
            msgProcessor processor = new msgProcessor();
            string result = processor.process(str);
            Console.WriteLine(result);


            Console.ReadLine();
        }
    }

    class msgProcessor
    {

        Filter[] filters = { new HTMLFilter(), new SessionFilter() };

        public string process(string str)
        {
            string r = str;

            foreach (Filter f in filters)
            {
                r = f.doFilter(r);
            }

            return r;
        }
    }

    interface Filter
    {
        string doFilter(string str);
    }

    class HTMLFilter : Filter
    {
        public string doFilter(string str)
        {
            string result = str.Replace("<", "[").Replace(">", "]");
            return result;
        }
    }

    class SessionFilter : Filter
    {
        public string doFilter(string str)
        {
            string result = str.Replace("TMD", "***").Replace("SB", "**");
            return result;
        }
    }

}

构成链条,但依然不是真正的职责链 进一步写法 CODE

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "大家好,<br/>S真TMD是SB... :)....";

            FilterChain fc = new FilterChain();
            fc.addFilter(new HTMLFilter()).addFilter(new SessionFilter());

            FilterChain fc2 = new FilterChain();
            fc2.addFilter(new FaceFilter());

            //有意思的一步
            fc.addFilter(fc2);

            msgProcessor processor = new msgProcessor(fc);
            string result = processor.process(str);
            Console.WriteLine(result);


            Console.ReadLine();
        }
    }

    class msgProcessor
    {

        FilterChain fc;

        public msgProcessor(FilterChain fc)
        {
            this.fc = fc;
        }

        public string process(string str)
        {
            return fc.doFilter(str);
        }
    }

    //由于FilterChain实现了Filter的接口,所以addFilter(Filter f)里面可以传递一个FilterChain
    class FilterChain : Filter
    {
        List<Filter> filters = new List<Filter>();

        public FilterChain addFilter(Filter f)
        {
            filters.Add(f);
            return this;
        }

        public string doFilter(string str)
        {
            string r = str;

            foreach (Filter f in filters)
            {
                r = f.doFilter(r);
            }

            return r;
        }
    }


    interface Filter
    {
        string doFilter(string str);
    }

    class HTMLFilter : Filter
    {
        public string doFilter(string str)
        {
            string result = str.Replace("<", "[").Replace(">", "]");
            return result;
        }
    }

    class SessionFilter : Filter
    {
        public string doFilter(string str)
        {
            string result = str.Replace("TMD", "***").Replace("SB", "**");
            return result;
        }
    }

    class FaceFilter : Filter
    {

        public string doFilter(string str)
        {
            string result = str.Replace(":)", "^V^");
            return result;
        }
    }
}

真正的职责链模式 大话设计模式 简化版 CODE

using System;
class Program
{
    static void Main(string[] args)
    {
        //初始化
        CommonMannger cm = new CommonMannger();
        MajordomoManger mm = new MajordomoManger();
        GeneralManager gm = new GeneralManager();
        //再职责链接起来
        cm.SetSuperiro(mm);
        mm.SetSuperiro(gm);

        //设计请假天数
        Request request = new Request();
        request.Number = 30;
        //开始请假,30天,明显是最后交到了总经理手上
        cm.RequestApplications(request);

        Console.ReadLine();

    }

    class Request
    {
        //申请天数
        private int number;
        public int Number
        {
            get { return number; }
            set { number = value; }
        }
    }




    abstract class Manager
    {
        protected Manager superior;

        public void SetSuperiro(Manager superior)
        {
            this.superior = superior;
        }

        abstract public void RequestApplications(Request request);
    }

    //经理
    class CommonMannger : Manager
    {
        public override void RequestApplications(Request request)
        {
            if (request.Number <= 2)
            {
                Console.WriteLine("经理批准 两天以下假请申请");
            }
            else
            {
                if (superior != null)
                    superior.RequestApplications(request);
            }
        }
    }

    //总监
    class MajordomoManger : Manager
    {
        public override void RequestApplications(Request request)
        {
            if (request.Number <= 5)
            {
                Console.WriteLine("总监批准 五天以下假请申请");
            }
            else
            {
                if (superior != null)
                    superior.RequestApplications(request);
            }
        }
    }

    //总经理
    class GeneralManager : Manager
    {
        public override void RequestApplications(Request request)
        {
            if (request.Number <= 100)
            {
                Console.WriteLine("总经理批准 一百天以下假请申请");
            }
            else
            {
                Console.WriteLine("你还是直接走人吧!");
            }
        }
    }
}


 

由于其他职责都是从 Manager 继承,所以都有SetSuperiro方法。

假设去找经理申请,可是经理没有权力的时候,这时候由于有了SetSuperiro他会去找在一开始传递给他的上一级的那个。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值