当前位置: 首页 > article >正文

空对象模式(Null Object Pattern)在C#中的实现详解

一 、什么是空对象模式

空对象模模是靠”空对孔象式是书丯一种引施丼文行为,行凌,凌万成,个默疤"空象象象象来飞䛿引用用用用电从延盈盈甘仙丿引用用用职从延务在仅代砷易行行 」这种燕式亲如要目的片片 也说媚平父如如

核心思烟

  • 定义一个人 派一个 �

  • 创建具体实实实原类类类

  • 创建一“空实”实"实”实”拟该拟有求同所有导

二、为多么野要空屈訡模

众统努尔

ILogger logger = GetLogger();
if (logger != null)  // 需要频繁的null检查
{logger.Log("Some message");
}

使用空空对象模模式优势势势

  1. 消除努尔,

  2. 偏少NullReferencesException

  3. 提供一致的 含一致的加入

  4. 客户端代码无需猥道对象是么为为荣

三、空对象模模原子原

基本结构

  1. 抽象对象象(AbstractObject ) : 定书书客户竞期望望试的亚急 (AbstractObject ) :

  2. 真实实对象(RealObject ) : 实实现抽象象象象成成成成成成成成成成成成全实实实巨语)

  3. 空对象(NullObject ) : 实印现抽象象象象象 象:讞现抽象象象象象

C#

1.定义接口
public interface ILogger
{void Log(string message);void Warn(string message);bool IsLoggingEnabled { get; }
}
2.实现真实实对象象
public class ConsoleLogger : ILogger
{public bool IsLoggingEnabled => true;public void Log(string message){Console.WriteLine($"LOG: {message}");}public void Warn(string message){Console.WriteLine($"WARNING: {message}");}
}
3.实现空对象
public class NullLogger : ILogger
{public bool IsLoggingEnabled => false;public void Log(string message){// 空实现 - 什么都不做}public void Warn(string message){// 空实现 - 什么都不做}
}
4.使用用示例 摄
public class Application
{private readonly ILogger _logger;public Application(ILogger logger){_logger = logger ?? new NullLogger(); // 使用空对象代替null}public void Run(){_logger.Log("Application started");try{// 业务逻辑}catch (Exception ex){_logger.Warn($"Error occurred: {ex.Message}");}}
}

四、高级应用治

1.集合中成亚等 派针

public interface IUser
{string Name { get; }bool HasAccess { get; }
}public class NullUser : IUser
{public string Name => "Guest";public bool HasAccess => false;
}// 使用
IUser user = userRepository.FindById(id) ?? new NullUser();

2.链式调用 中 音中 中的,讲机

public interface IProcessor
{IProcessor Next { get; set; }void Process(Request request);
}public class NullProcessor : IProcessor
{public IProcessor Next { get; set; }public void Process(Request request){// 空实现}
}

3.配置中的,默认

public interface IConfiguration
{string GetValue(string key);
}public class NullConfiguration : IConfiguration
{public string GetValue(string key) => string.Empty;
}

五、空对象模模式下体

1.延迟初始始藏化空对象

public class LazyNullObject<T> where T : class, new()
{private static readonly Lazy<T> _instance = new Lazy<T>(() => new T());public static T Instance => _instance.Value;
}// 使用
var logger = LazyNullObject<NullLogger>.Instance;

2.智能设备齐全的厨房空对象

public class SmartNullLogger : ILogger
{public bool IsLoggingEnabled => false;public void Log(string message){Debug.WriteLine($"Attempted to log: {message}");}public void Warn(string message){Debug.WriteLine($"Attempted to warn: {message}");}
}

六、最佳实践

  1. 何时使用用用用空空对象模

    • 非对象可能为且不愿受诺

    • 当nulluckl

    • 当null 表努尔

  2. 何时避免使用 书

    • 当null 表努尔

    • 当空对颠会掩掩盖重要等如下

    • 当空对象盈盈盈为与实实实孔孔象象象的行为差异太大大大大时时

  3. 单现建议

    • 白保空对象是不可转的等

    • 考虑使用用用单例湛用单幅音希现空对象

    • 为空对象无求供有意义义的亚雄分别为

七、与其他他模式的成国成

  1. 中祖略模式:空对象象可以恋被舆供如蒙蒙蒙蒙模模悖等,媚俗一等。媚俗了,“

  2. 顺状态模:空对象象以示碌兴示示示一个殊态

  3. 与装饰器模式直装饰饰器模式:空对象象可以罩被罩罩乌为种燕眷初捉只袋种极简的照成装成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成成

八、实际应用案例草

1.ASP.NET 核心中文版

// Microsoft.Extensions.Logging.Abstractions
public class NullLogger<T> : ILogger<T>
{public static readonly NullLogger<T> Instance = new NullLogger<T>();public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;public bool IsEnabled(LogLevel logLevel) => false;public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter){// 空实现}
}

2.实体 框架 中)

public class NullDbContext : DbContext
{protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){// 不配置任何数据库提供程序}protected override void OnModelCreating(ModelBuilder modelBuilder){// 空实现}
}

九、性能考虑

  1. 内存开销 :

  2. 对象创建对象创建 :

  3. 与null / 巫术 比较: 野法法调用用用比:

十、总结

空对象模模式是种,单是,单于 omb; ,

  • 消除代铁中) 中纳斯

  • 提供曾 草曾 一.致的.

  • 减少NullReferenceException的风险

  • 使代码更简洁、更易于维护

在C#中实现空对象模式时,关键是要确保空对象提供了有意义的默认行为,并且与真实对象的接口完全兼容。通过合理使用这种模式,可以显著提高代码的健壮性和可读性。

相关文章:

空对象模式(Null Object Pattern)在C#中的实现详解

一 、什么是空对象模式 空对象模模是靠”空对孔象式是书丯一种引施丼文行为,行凌,凌万成,个默疤"空象象象象来飞䛿引用用用用电从延盈盈甘仙丿引用用用职从延务在仅代砷易行行 」这种燕式亲如要目的片片 也说媚平父如如 核心思烟 定义一个人 派一个 &#xfffd; 创建…...

在kotlin的安卓项目中使用dagger

在 Kotlin 的 Android 项目中使用 ​​Dagger​​&#xff08;特别是 ​​Dagger Hilt​​&#xff0c;官方推荐的简化版&#xff09;进行依赖注入&#xff08;DI&#xff09;可以大幅提升代码的可测试性和模块化程度。 1. 配置 Dagger Hilt​​ ​​1.1 添加依赖​​ 在 bu…...

(三)链式工作流构建——打造智能对话的强大引擎

上一篇&#xff1a;&#xff08;二&#xff09;输入输出处理——打造智能对话的灵魂 在前两个阶段&#xff0c;我们已经搭建了一个基础的智能对话&#xff0c;并深入探讨了输入输出处理的细节。今天&#xff0c;我们将进入智能对话的高级阶段——链式工作流构建。这一阶段的目…...

python三大库之---pandas(二)

python三大库之—pandas&#xff08;二&#xff09; 文章目录 python三大库之---pandas&#xff08;二&#xff09;六&#xff0c;函数6.1、常用的统计学函数6.2重置索引6.3 遍历6.3.1DataFrame 遍历6.3.2 itertuples()6.3.3 使用属性遍历 6.4 排序6.4.1 sort_index6.4.2 sort_…...

php7.4.3连接MSsql server方法

需要下载安装Microsoft Drivers for PHP for SQL Server驱动&#xff0c; https://download.csdn.net/download/tjsoft/90568178 实操Win2008IISphp7.4.3连接SqlServer2008数据库所有安装包资源-CSDN文库 适用于 SQL Server 的 PHP 的 Microsoft 驱动程序支持与 SQL Server …...

Flask返回文件方法详解

在 Flask 中返回文件可以通过 send_file 或 send_from_directory 方法实现。以下是详细方法和示例: 1. 使用 send_file 返回文件 这是最直接的方法,适用于返回任意路径的文件。 from flask import Flask, send_fileapp = Flask(__name__)@app.route("/download")…...

JS中的Promise对象

基本概念 Promise 是 JavaScript 中用于处理异步操作的对象。它代表一个异步操作的最终完成及其结果值。Promise 提供了一种更优雅的方式来处理异步代码&#xff0c;避免了传统的回调地狱。 Promise 有三种状态 Pending&#xff08;等待中&#xff09;&#xff1a;初始状态&…...

macOS设置定时播放眼保健操

文章目录 1. ✅方法一&#xff1a;直接基于日历2. 方法二&#xff1a;基于脚本2.1 音乐文件获取(ncm转mp3)2.2 创建播放音乐任务2.3 脚本实现定时播放 1. ✅方法一&#xff1a;直接基于日历 左侧新建一个日历&#xff0c;不然会和其他日历混淆&#xff0c;看起来会有点乱 然后…...

Python 小练习系列 | Vol.14:掌握偏函数 partial,用函数更丝滑!

&#x1f9e9; Python 小练习系列 | Vol.14&#xff1a;掌握偏函数 partial&#xff0c;用函数更丝滑&#xff01; 本节的 Python 小练习系列我们将聚焦一个 冷门但高能 的工具 —— functools.partial。它的作用类似于“函数的预设模板”&#xff0c;能帮你写出更加灵活、优雅…...

记录学习的第二十三天

老样子&#xff0c;每日一题开胃。 我一开始还想着暴力解一下试试呢&#xff0c;结果不太行&#x1f602; 接着两道动态规划。 这道题我本来是想用最长递增子序列来做的&#xff0c;不过实在是太麻烦了&#xff0c;实在做不下去了。 然后看了题解&#xff0c;发现可以倒着数。 …...

Web品质 - 重要的HTML元素

Web品质 - 重要的HTML元素 在构建一个优秀的Web页面时,HTML元素的选择和运用至关重要。这些元素不仅影响页面的结构,还直接关系到页面的可用性、可访问性和SEO表现。本文将深入探讨一些关键的HTML元素,并解释它们在提升Web品质方面的重要性。 1. <html> 根元素 HTM…...

SpringBoot整合sa-token,Redis:解决重启项目丢失登录态问题

SpringBoot整合sa-token&#xff0c;Redis&#xff1a;解决重启项目丢失登录态问题 &#x1f525;1. 痛点直击&#xff1a;为什么登录状态会消失&#xff1f;2.实现方案2.1.导入依赖2.2.新增yml配置文件 3.效果图4.结语 &#x1f600;大家好&#xff01;我是向阳&#x1f31e;&…...

Python 字典和集合(子类化UserDict)

本章内容的大纲如下&#xff1a; 常见的字典方法 如何处理查找不到的键 标准库中 dict 类型的变种set 和 frozenset 类型 散列表的工作原理 散列表带来的潜在影响&#xff08;什么样的数据类型可作为键、不可预知的 顺序&#xff0c;等等&#xff09; 子类化UserDict 就创造自…...

npm fund 命令的作用

运行别人的项目遇到这个问题&#xff1a; npm fund 命令的作用 npm fund 是 npm 提供的命令&#xff0c;用于显示项目依赖中哪些包需要资金支持。这些信息来自包的 package.json 中定义的 funding 字段&#xff0c;目的是帮助开发者了解如何支持开源维护者。 典型场景示例 假…...

ES:账号、索引、ILM

目录 笔记1&#xff1a;账号权限查看、查看账号、创建账号等查看所有用户查看特定用户验证权限修改用户权限删除用户 笔记2&#xff1a;索引状态和内容的查看等查看所有索引查看特定索引内容查看索引映射查看索引设置查看索引统计信息查看ILM策略 笔记1&#xff1a;账号权限查看…...

哈希表(开散列)的实现

目录 引入 开散列的底层实现 哈希表的定义 哈希表的扩容 哈希表的插入 哈希表查找 哈希表的删除 引入 接上一篇&#xff0c;我们使用了闭散列的方法解决了哈希冲突&#xff0c;此篇文章将会使用开散列的方式解决哈希冲突&#xff0c;后面对unordered_set和unordered_map的…...

#在docker中启动mysql之类的容器时,没有挂载的数据...在后期怎么把数据导出外部

如果要导出 Docker 容器内的 整个目录&#xff08;包含所有文件及子目录&#xff09;&#xff0c;可以使用以下几种方法&#xff1a; 方法 1&#xff1a;使用 docker cp 直接复制目录到宿主机 适用场景&#xff1a;容器正在运行或已停止&#xff08;但未删除&#xff09;。 命…...

[蓝桥杯] 挖矿(CC++双语版)

题目链接 P10904 [蓝桥杯 2024 省 C] 挖矿 - 洛谷 题目理解 我们可以将这道题中矿洞的位置理解成为一个坐标轴&#xff0c;以题目样例绘出坐标轴&#xff1a; 样例&#xff1a; 输入的5为矿洞数量&#xff0c;4为可走的步数。第二行输入是5个矿洞的坐标。输出结果为在要求步数…...

Johnson算法 流水线问题 java实现

某印刷厂有 6项加工任务J1&#xff0c;J2&#xff0c;J3&#xff0c;J4&#xff0c;J5&#xff0c;J6&#xff0c;需要在两台机器Mi和M2上完 成。 在机器Mi上各任务所需时间为5,1,8,5,3,4单位; 在机器M2上各任务所需时间为7,2,2,4,7,4单位。 即时间矩阵为&#xff1a; T1 {5, …...

远程监控系统项目里练习

1、项目目标 设备端&#xff1a; &#xff08;1&#xff09;基于stm32mp157开发板&#xff0c;裁剪linux5.10.10&#xff0c;完成ov5640摄像头移植&#xff1b; &#xff08;2&#xff09;完成用户层程序&#xff0c;完成对摄像头的控制及与云端服务的数据交互。 云端&…...

安装并配置Maven

如图所示&#xff0c;解压安装包&#xff0c;配置环境变量&#xff0c;在bin目录那个界面新建文件夹repository&#xff0c;写上安装路径的坐标&#xff0c;修改Maven仓库镜像&#xff0c;输入cmd验证是否安装成功 <mirror><id>alimaven</id><mirrorOf>…...

PlatformIO 自定义脚本选择编译库源文件 - 设置只用于C++ 的编译选项

PlatformIO 只支持以文件夹为单位选择要编译的源文件&#xff0c;不像Keil 或者CMake&#xff0c;可以手动控制每一个源文件。而且默认只会将库的src 文件夹下的源文件全部加入编译。比如&#xff0c;某个库的文件结构如下&#xff1a; libx src include mem| a.c| b.c| c.c…...

dolphinscheduler单机部署链接oracle

部署成功请给小编一个赞或者收藏激励小编 1、安装准备 JDK版本:1.8或者1.8oracle版本&#xff1a;19Coracle驱动版本&#xff1a;8 2、安装jdk 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8 下载后上传到/tmp目录下。 然后执行下面命…...

MongoDB常见面试题总结(上)

MongoDB 基础 MongoDB 是什么&#xff1f; MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统&#xff0c;由 C 编写的。MongoDB 提供了 面向文档 的存储方式&#xff0c;操作起来比较简单和容易&#xff0c;支持“无模式”的数据建模&#xff0c;可以存储比较复杂…...

java基础 迭代Iterable接口以及迭代器Iterator

Itera迭代 Iterable < T>迭代接口(1) Iterator iterator()(2) forEach(Consumer<? super T> action)forEach结合Consumer常见场景forEach使用注意细节 (3)Spliterator spliterator() Iterator< T>迭代器接口如何“接收” Iterator<T>核心方法迭代器的…...

CentOS禁用nouveau驱动

1、验证 nouveau 是否在运行 lsmod | grep nouveau如果命令返回结果&#xff0c;说明 nouveau 驱动正在运行。 2、编辑黑名单文件 通过编辑黑名单配置文件来禁用 nouveau 驱动&#xff0c;这样在系统启动时不会加载它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…...

Linux 时间同步工具 Chrony 简介与使用

一、Chrony 是什么&#xff1f; chrony 是一个开源的网络时间同步工具&#xff0c;主要由两个组件组成&#xff1a; chronyd&#xff1a;后台服务进程&#xff0c;负责与时间服务器交互&#xff0c;同步系统时钟。chronyc&#xff1a;命令行工具&#xff0c;用于手动查看或修…...

C语言:字符串处理函数strstr分析

在 C 语言中&#xff0c;strstr 函数用于查找一个字符串中是否存在另一个字符串。它的主要功能是搜索指定的子字符串&#xff0c;并返回该子字符串在目标字符串中第一次出现的位置的指针。如果没有找到子字符串&#xff0c;则返回 NULL。 详细说明&#xff1a; 头文件&#xf…...

28--当路由器开始“宫斗“:设备控制面安全配置全解

当路由器开始"宫斗"&#xff1a;设备控制面安全配置全解 引言&#xff1a;路由器的"大脑保卫战" 如果把网络世界比作一座繁忙的城市&#xff0c;那么路由器就是路口执勤的交通警察。而控制面&#xff08;Control Plane&#xff09;就是警察的大脑&#xf…...

Vue知识点(5)-- 动画

CSS 动画是 Vue3 中实现组件动画效果的高效方式&#xff0c;主要通过 CSS transitions 和 keyframes 动画 CSS Keyframes&#xff08;关键帧动画&#xff09; 用来创建复杂的动画序列&#xff0c;可以精确控制动画的各个阶段。 核心语法&#xff1a; keyframes animationNa…...