责任链模式-C#实现

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

主要涉及两个角色:
抽象处理者角色(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;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/741015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【测试开发学习历程】Linux用户管理+文件权限管理

目录 一、用户管理 &#xff08;一&#xff09;用户和用户组的基本概念 1.概念 2.设置原因 3.用户与用户组的关系 4.用户类型 &#xff08;二&#xff09;用户的创建、修改属性和删除用户 1.用户信息文件 2.创建用户 3.修改用户密码 4.修改用户信息 5.用户查询 6.…

MAMP Pro 站点404 Nginx 配置

MAMP Pro 站点配置 if (!-e $request_filename) {rewrite ^(.*)$ /index.php?s/$1 last;break; }

第十四届蓝桥杯C++B组编程题题目以及题解

a.冶炼金属&#xff08;二分&#xff09; 思路&#xff1a; 设任意一条冶炼记录投入金属数量为a,产出金属为b. 对于每一条冶炼记录我们都可以得到 一个转换率V的范围&#xff1a; b<a/v<b1即a/b< v <a/(b1) 为什么是b1呢&#xff1f;因为既然能产出b个金属&#xf…

实现的一个网页版的简易表白墙

实现的一个网页版的表白墙 实现效果 代码截图 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…

【Java】初级篇:基本语法

一、变量与运算符 标识符命名规则 由26个英文字母大小写、0-9、_或$组成&#xff1b;不可以以数字开头&#xff1b;不能单用关键字和保留字&#xff1b;区分大小写&#xff1b;不包含空格。 【包名&#xff1a;所有字母小写|类名、接口名&#xff1a;多单词组成时所有字母首字…

1.6数组

一.序言 数组是一组类型相同类型元素的集合&#xff0c;数组的定长的&#xff08;数组的长度一旦被定义&#xff0c;长度不可改变&#xff09;。 数组在内存当中是一块连续的空间&#xff0c;可以保存相同类型的多个元素。 二.一维数组 2.1.数组的创建 int arr1[10]; …

Android的UI渲染机制(一)

应用程序与Surface的关系&#xff0c;从应用程序的Activity开始&#xff0c;一路追踪到ViewRoot、WindowManager Service。 SurfaceFlinger则主要负责视图的显示&#xff0c;其管理多个surface进行图像合成。WindowManager Service由System_Server进程启动&#xff0c;SurfaceF…

IDEA 设置信息及插件同步配置

所需插件&#xff1a; 第一步&#xff1a;打开登录界面&#xff0c;进行登录 第二步&#xff1a;再次点击

Go——运算符,变量和常量,基本类型

一.运算符 Go语言内置的运算符有&#xff1a; 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 1.1 算术运算符 注意&#xff1a;(自增)和--(自减)在go语言中是单独的语句&#xff0c;并不是运算符。 1.2 关系运算符 1.3 逻辑运算符 1.4 位运算符 位运算符对整数在内存…

【Linux】Linux小结

LVS、Nginx、HAproxy的区别 LVS、Nginx和HAproxy都是常见的负载均衡器&#xff0c;用于将网络负载分散到多个服务器上&#xff0c;以提高系统的可用性和性能 功能不同&#xff1a; LVS是一个Linux内核模块&#xff0c;在网络层&#xff08;第四层&#xff09;运行的。 Nginx和…

基于springboot+vue实现药品信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springbootvue实现药品信息管理系统演示 摘要 本文介绍了一种基于SpringBoot的药品信息管理系统的设计与实现。该系统旨在提高药品管理的效率和准确性&#xff0c;包括药品信息的录入、修改、查询和删除、药品入库、出库等功能。该系统采用了SpringBoot框架、MySQL数据库、…

[GPU]2.编译.cu文件

在编译.cu文件的时候&#xff0c;需要先确定自己已经安装了CUDA&#xff0c;并将其配置到系统环境中。 当然这个的前提是——你的显卡得是nvida的&#xff0c;你才能安装这个工具 如果你完成了这些的话&#xff0c;编译.cu文件就比较容易了&#xff0c;比如这个文件&#xff…

金三银四,求职攻略:解锁面试密码,赢在职场起跑线

春风拂面&#xff0c;金三银四的求职季如期而至。 你是否已经准备好在这场求职大战中脱颖而出&#xff0c;斩获心仪的职位&#xff1f;是不是还在为如何准备一份吸引人的简历而犯愁&#xff1f;是不是担心自己在面试中紧张失言&#xff0c;错失良机&#xff1f;是不是对如何了…

从入门到入魔,100个Python实战项目练习(附答案)!

大家好&#xff0c;我是彭涛。 之前给大家整理的资料&#xff0c;都是理论性的&#xff0c;虽然每一个知识点都给出了对应的示例代码&#xff0c;但是好多人还是感觉有一点点杂乱&#xff0c;如果有系统的实战项目练习就好了。 所以&#xff0c;应大家的需求&#xff0c;我们为…

HarmonyOS应用开发-Stage模型开发概述

基本概念 UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。提供了应用UI开发所必需的能力&#xff1a;多种组件、布局计算、动画能力、UI交互、绘制。 方舟开发框架针对开发者提供了两种开发范式&#xff1a; 基于ArkTS…

【yolov8和yolov5】用命令快速着手训练

文章目录 1.yolov81.1.创建conda环境1.2.下载代码和环境1.3.YOLOv8训练、自测和预测的代码及解释1.3.1. YOLOv8 训练代码&#xff1a;1.3.2.yolov8 自测代码&#xff1a;1.3.3.yolov8 推理代码&#xff1a;1.3.4.注意&#xff1a; 2.yolov52.1.创建conda环境2.2.下载代码和环境…

简单聊一聊项目中用反射来做过啥【Java基础题】

1.什么是反射机制 反射允许(在运行时动态地)对封装类的字段、方法、构造函数的信息进行编程访问 在我们的代码中&#xff0c;使用构造器直接生成对象、直接访问对象、对象的成员等方式&#xff0c;是清晰直观的。但在有些场景中&#xff0c;需要在运行时动态地操作这些成员&…

Cisco Packet Tracer模拟器实现路由器的路由配置及网络的安全配置

1. 内容 1. 配置路由器实现多个不同网络间的通信&#xff0c;路由器提供的路由协议包括静态路由协议、RIP动态路由、OSPF动态路由协议等等&#xff0c;训练内容包括路由器的静态路由配置、路由器的RIP动态路由配置、路由器的OSPF动态路由配置以及路由器的路由重分布配置。 2.…

LaneNet 论文阅读

论文链接 Towards End-to-End Lane Detection: an Instance Segmentation Approach 0. Abstract 在本文中&#xff0c;将车道检测问题转化为实例分割问题——其中每个车道形成自己的实例——可以进行端到端训练为了在拟合车道之前对分段车道实例进行参数化&#xff0c;应用基…

Seata源码流程图

1.第一阶段分支事务的注册 流程图地址&#xff1a;https://www.processon.com/view/link/6108de4be401fd6714ba761d 2.第一阶段开启全局事务 流程图地址&#xff1a;https://www.processon.com/view/link/6108de13e0b34d3e35b8e4ef 3.第二阶段全局事务的提交 流程图地址…