• 设计模式C#实现(十四)——责任链模式


     

     

    意图

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

    适用性

    在以下条件下使用:

    • 有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
    • 你想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。
    • 可处理一个请求的对象集合应该被动态指定。

    结构

    责任链UML

    实现

    实现一个邮件处理系统,将邮件按照类别交给不同的对象处理。
    已经分类的邮件

        public class Request
        {
            public Request(string type)
            {
                Type = type;
            }
            private string _content;
            public string Type { get; set; }
        }
    

    处理的抽象,类似链表,自身包含指向下一个处理节点的对象

        public abstract class Handler
        {
            protected Handler _nextHandler;
            public abstract void ProcessRequest(Request request);
            public void SetNext(Handler handler)
            {
                _nextHandler = handler;
            }
        }
    

    对不同类型进行处理的对象

        //粉丝邮件处理
        public class FanHandler:Handler
        {
            public override void ProcessRequest(Request request)
            {
                if (request.Type=="fan")
                {
                    Console.WriteLine("fan's email process");
                }
                else
                {
                    _nextHandler.ProcessRequest(request);
                }
            }
        }
        //垃圾邮件处理
        public class SpamHandler : Handler
        {
            public override void ProcessRequest(Request request)
            {
                if (request.Type == "spam")
                {
                    Console.WriteLine("spam delete");
                }
                else
                {
                    _nextHandler.ProcessRequest(request);
                }
            }
        }
        //抱怨和意见邮件处理
        public class ComplaintHandler:Handler
        {
            public override void ProcessRequest(Request request)
            {
                if (request.Type=="complaint")
                {
                    Console.WriteLine("complaint process");
                }
                else
                {
                    _nextHandler.ProcessRequest(request);
                }
            }
        }
        //其他邮件处理
        public class DefaultHandler:Handler
        {
            public override void ProcessRequest(Request request)
            {
                Console.WriteLine("Do some thing!");
            }
        }
    

    使用之前,先要将责任链串联起来

     class Program
        {
            static void Main(string[] args)
            {
                //发送者
                var fan = new Request("fan");
                var spam = new Request("spam");
                var complaint = new Request("complaint");
                var other = new Request("other");
                //接受者
                var fanHandler = new  FanHandler();
                var spamHandler = new SpamHandler();
                var complaintHandler = new ComplaintHandler();
                var defaultHandler = new  DefaultHandler();
    
                //构造责任链
                fanHandler.SetNext(spamHandler);
                spamHandler.SetNext(complaintHandler);
                complaintHandler.SetNext(defaultHandler);
    
                //请求交由责任链头节点处理
                fanHandler.ProcessRequest(fan);
                fanHandler.ProcessRequest(spam);
                fanHandler.ProcessRequest(complaint);
                fanHandler.ProcessRequest(other);
                Console.ReadKey();
    
            }
        }
    

    运行结果
    运行结果

    效果

    1. 降低耦合度
    2. 增强了给对象指派职责的灵活性
    3. 不保证被接受(用一个默认处理类来解决这个问题)

    参考

    1. 《Head First 设计模式》
    2. 《设计模式》
    3. C#设计模式(21)——责任链模式
  • 相关阅读:
    SqlServer报错:指定的网络名不再可用
    Flutter Build apk 错误(一)
    修改项目语言为C#8.0
    Foxmail6.5 ERR LOGIN FAIL 重新输入口令
    VSCode调试Flutter的问题解决
    解决localdb中文智能的问题
    EF Oracle:错误 175
    清除SqlServer日志
    EF:根据实体类生成表结构SQL
    修改TNSLSNR的端口
  • 原文地址:https://www.cnblogs.com/castdream/p/5078124.html
Copyright © 2020-2023  润新知