责任链模式指的是——某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。
将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。
主要涉及两个角色:
抽象处理者角色(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;}}
}