责任链模式-C#实现

本文介绍了责任链模式,包括其定义、角色、意图、优缺点及使用场景,通过WPF实例展示了如何在模型中实现抽象处理者和具体处理者,以及在视图和ViewModel中应用该模式。

责任链模式指的是——某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。
将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。

主要涉及两个角色:
抽象处理者角色(Handler):定义出一个处理请求的接口。这个接口通常由接口或抽象类来实现。
具体处理者角色(ConcreteHandler):具体处理者接受到请求后,可以选择将该请求处理掉,或者将请求传给下一个处理者。
因此,每个具体处理者需要保存下一个处理者的引用,以便把请求传递下去。

意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,
并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,
所以职责链将请求的发送者和请求的处理者解耦了。

何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。

缺点: 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。

使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
 

该实例基于WPF实现,直接上代码,下面为三层架构的代码。

一 Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    //1,创建抽象接口标准类: 日志记录器类
    public abstract class AbstractLogger
    {
        public static int DEBUG = 0;
        public static int INFO = 1;
        public static int WARN = 2;
        public static int ERROR = 3;
        public static int FATAL = 4;

        protected int _level;

        //责任链中的下一个元素
        private AbstractLogger nextLogger;

        //设置下一个责任链
        public AbstractLogger NextLogger { set => nextLogger = value; }


        //根据日志级别打印日志
        public void logMessage(int level, string message)
        {
            if (this._level <= level)
            {
                write(message);
            }

            if (nextLogger != null)
            {
                nextLogger.logMessage(level, message);
            }
        }

        public abstract void write(string message);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    //2,创建具体的实体类
    internal class DebugLogger : AbstractLogger
    {
        public string LogInfo { get; set; }


        //指定日志级别
        public DebugLogger(int level)
        {
            this._level = level;
        }

        public override void write(string message)
        {
            LogInfo = "debug:" + message;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    internal class ErrorLogger : AbstractLogger
    {
        public string LogInfo { get; set; }


        //指定日志级别
        public ErrorLogger(int level)
        {
            this._level = level;
        }

        public override void write(string message)
        {
            LogInfo = "error:" + message;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    internal class FatalLogger : AbstractLogger
    {
        public string LogInfo { get; set; }


        //指定日志级别
        public FatalLogger(int level)
        {
            this._level = level;
        }

        public override void write(string message)
        {
            LogInfo = "fatal:" + message;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    internal class InfoLogger : AbstractLogger
    {
        public string LogInfo { get; set; }


        //指定日志级别
        public InfoLogger(int level)
        {
            this._level = level;
        }

        public override void write(string message)
        {
            LogInfo = "info:" + message;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.责任链模式
{
    internal class WarnLogger : AbstractLogger
    {
        public string LogInfo { get; set; }


        //指定日志级别
        public WarnLogger(int level)
        {
            this._level = level;
        }

        public override void write(string message)
        {
            LogInfo = "warning:" + message;
        }
    }
}

二 View

<Window x:Class="设计模式练习.View.责任链模式.ChainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:设计模式练习.View.责任链模式"
        mc:Ignorable="d"
        Title="ChainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Button Content="debug日志" Grid.Row="0" Command="{Binding debugCommand}"/>
            <Button Content="info日志" Grid.Row="1" Command="{Binding infoCommand}"/>
            <Button Content="warm日志" Grid.Row="2" Command="{Binding warmCommand}"/>
            <Button Content="error日志" Grid.Row="3" Command="{Binding errorCommand}"/>
            <Button Content="fatal日志" Grid.Row="4" Command="{Binding fatalCommand}"/>
        </Grid>
        <TextBlock Text="{Binding Res}" Grid.Column="1" FontSize="30" VerticalAlignment="Center" TextWrapping="Wrap"/>
    </Grid>
</Window>

三 ViewModel

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 设计模式练习.Model.责任链模式;

namespace 设计模式练习.ViewModel.责任链模式
{
    partial class ChainWindow_ViewModel : ObservableObject
    {
        [ObservableProperty]
        private string res;

        [RelayCommand]
        private void debug()
        {
            AbstractLogger logger = new DebugLogger(AbstractLogger.DEBUG);
            logger.logMessage(AbstractLogger.DEBUG, "程序执行了计算操作,输出级别为:debug");
            Res = (logger as DebugLogger).LogInfo;
        }

        [RelayCommand]
        private void info()
        {
            AbstractLogger logger = new InfoLogger(AbstractLogger.INFO);
            logger.logMessage(AbstractLogger.INFO, "程序执行了选择算法,输出级别为:info");
            Res = (logger as InfoLogger).LogInfo;
        }

        [RelayCommand]
        private void warm()
        {
            AbstractLogger logger = new WarnLogger(AbstractLogger.WARN);
            logger.logMessage(AbstractLogger.WARN, "程序中检测到异常计算表达式,输出级别为:warm");
            Res = (logger as WarnLogger).LogInfo;
        }

        [RelayCommand]
        private void error()
        {
            AbstractLogger logger = new ErrorLogger(AbstractLogger.ERROR);
            logger.logMessage(AbstractLogger.ERROR, "程序存在对象空引用,输出级别为:error");
            Res = (logger as ErrorLogger).LogInfo;
        }

        [RelayCommand]
        private void fatal()
        {
            AbstractLogger logger = new FatalLogger(AbstractLogger.FATAL);
            logger.logMessage(AbstractLogger.FATAL, "程序运行过程中导致操作系统崩溃,输出级别为:fatal");
            Res = (logger as FatalLogger).LogInfo;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_shenbing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值