C# 设计模式的六大原则(SOLID)
C# 设计模式的六大原则(SOLID)
引言
在面向对象编程中,设计模式提供了高效、可复用和可维护的代码结构。SOLID原则是软件设计中的一组重要原则,用于确保代码具有良好的可维护性、可扩展性和灵活性。SOLID是五个设计原则的首字母缩写,广泛应用于面向对象编程中,尤其是在大型项目中。
本文将详细介绍SOLID五大设计原则以及它们在C#中的应用,并进一步探讨有时被扩展为“六大原则”的情况。
1. 单一职责原则(SRP)
定义:
单一职责原则(Single Responsibility Principle)规定一个类应该只有一个职责,并且该类应该只有一个引起它变化的原因。也就是说,一个类不应该承担过多的责任,否则会变得难以维护和扩展。
在C#中的实现:
public class OrderProcessor
{public void ProcessOrder(Order order){// 处理订单逻辑}
}public class OrderPrinter
{public void PrintOrder(Order order){// 打印订单逻辑}
}
解释:
在这个例子中,OrderProcessor
类只负责处理订单,而 OrderPrinter
类只负责打印订单。通过分离不同的职责,使得每个类的功能更加专一、简洁。
优势:
- 提高可维护性:更改一个类的逻辑时,不会影响其他无关的部分。
- 增强可测试性:由于职责明确,单元测试变得更加简单。
2. 开闭原则(OCP)
定义:
开闭原则(Open/Closed Principle)表明,“软件实体(类、模块、函数等)应该对扩展开放,对修改封闭”。这意味着当需求变化时,我们应该通过添加新代码来扩展系统,而不是修改现有代码。
在C#中的实现:
public interface IPaymentMethod
{void Pay();
}public class CreditCardPayment : IPaymentMethod
{public void Pay() { /* 支付实现 */ }
}public class PayPalPayment : IPaymentMethod
{public void Pay() { /* 支付实现 */ }
}public class PaymentProcessor
{public void ProcessPayment(IPaymentMethod paymentMethod){paymentMethod.Pay();}
}
解释:
通过使用接口(IPaymentMethod
),我们可以为不同的支付方式实现扩展。增加新的支付方式时,我们只需创建新的实现类,而不需要修改 PaymentProcessor
类。
优势:
- 灵活性:新功能可以通过增加新类而不破坏现有系统的稳定性。
- 增强可扩展性:能够适应系统需求的变化,而无需修改已有的代码。
3. 里氏替换原则(LSP)
定义:
里氏替换原则(Liskov Substitution Principle)规定,子类对象应该能够替换父类对象,并且不会改变程序的正确性。也就是说,子类必须遵循父类的行为约定,并可以在任何父类对象出现的地方替代父类。
在C#中的实现:
public class Bird
{public virtual void Fly() { /* 通用飞行实现 */ }
}public class Sparrow : Bird
{public override void Fly() { /* 麻雀飞行实现 */ }
}public class Penguin : Bird
{public override void Fly(){throw new NotSupportedException("企鹅不能飞");}
}
解释:
在上面的代码中,Penguin
类违反了里氏替换原则,因为企鹅不能飞,强制让其实现 Fly
方法不符合实际需求。我们可以通过接口或其他设计方式来避免这种问题。
优势:
- 增强代码的可替换性:子类应该能无缝替换父类,确保系统的健壮性。
- 减少代码错误:遵循该原则避免不必要的设计冲突。
4. 接口隔离原则(ISP)
定义:
接口隔离原则(Interface Segregation Principle)要求类应该仅实现它需要使用的接口,而不应该强迫它实现不需要的方法。换句话说,接口应该细化,而不是做一个“臃肿”的接口。
在C#中的实现:
public interface IPrinter
{void Print();
}public interface IFax
{void Fax();
}public class MultiFunctionMachine : IPrinter, IFax
{public void Print() { /* 打印实现 */ }public void Fax() { /* 传真实现 */ }
}public class Printer : IPrinter
{public void Print() { /* 打印实现 */ }
}
解释:
在这个例子中,Printer
类只实现了与打印相关的接口,而 MultiFunctionMachine
类同时实现了打印和传真接口。根据接口隔离原则,如果一个类只关心打印,那么它不应该实现传真接口。
优势:
- 减少不必要的依赖:减少类与类之间的不必要耦合。
- 增强代码灵活性:提高代码的复用性,减少修改的影响范围。
5. 依赖倒转原则(DIP)
定义:
依赖倒转原则(Dependency Inversion Principle)要求高层模块不应该依赖低层模块,而应该依赖抽象。具体来说,应该依赖接口或抽象类,而不是具体的实现类。
在C#中的实现:
public interface IDatabase
{void SaveData();
}public class SQLServerDatabase : IDatabase
{public void SaveData() { /* SQL Server 数据库实现 */ }
}public class BusinessLogic
{private readonly IDatabase _database;public BusinessLogic(IDatabase database){_database = database;}public void ProcessData() { _database.SaveData(); }
}
解释:
在这个例子中,BusinessLogic
类依赖于 IDatabase
接口,而不是具体的 SQLServerDatabase
类。通过这种方式,我们可以轻松地将不同的数据库实现替换到 BusinessLogic
中。
优势:
- 提高模块的灵活性:减少模块之间的耦合,增强可扩展性。
- 便于单元测试:可以使用模拟对象(mock)轻松替换数据库实现,进行单元测试。
6. 总结
SOLID原则是现代面向对象设计中的基石,帮助开发人员编写高效、可维护、可扩展的代码。通过遵循这些原则,可以极大提高系统的质量、可读性和可测试性。在实际开发中,理解和应用SOLID原则对于构建稳定和高质量的应用程序至关重要。
希望这篇博客能够帮助你更好地理解并应用SOLID原则。如果你有任何问题,欢迎在评论区讨论或者留言交流!
相关文章:
C# 设计模式的六大原则(SOLID)
C# 设计模式的六大原则(SOLID) 引言 在面向对象编程中,设计模式提供了高效、可复用和可维护的代码结构。SOLID原则是软件设计中的一组重要原则,用于确保代码具有良好的可维护性、可扩展性和灵活性。SOLID是五个设计原则的首字母…...
MQ-导读
什么是MQ? MQ是一款消息中间件,通常被称为"消息队列",用于分布式架构中上下文的异步通信。 举个例子 就拿登录来说,用户在登录的时候需要去进行一些其他的操作,比如风控、短信、记录日志,如果采用同步的方式…...
Spring MVC的@ResponseBody与@RequestBody
ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。 RequestBody注解用于读取http请求的内容(字符串),通过springmv…...
常见硬件及其对应的驱动模块列表
常见硬件及其对应的驱动模块列表 1. 电机类 硬件设备驱动模块功能步进电机ULN2003、A4988、DRV8825提供电流和电压,控制步进和方向直流电机L298N、L293D、TB6612FNG提供双向电流控制,实现正反转和调速伺服电机无(直接 PWM 控制)控…...
IDEA开发Java应用的初始化设置
一、插件安装 如下图所示: 1、Alibaba Java Coding Guidelines 2.1.1 阿里开发者规范,可以帮忙本地自动扫描出不符合开发者规范的代码,甚至是代码漏洞提示。 右击项目,选择《编码规约扫描》,可以进行本地代码规范扫…...
系统架构师考试-ABSD基于架构的设计方法
概念 ABSD是体系结构驱动,是指构成体系结构的软件构件和类的组合驱动的。 ABSD强调由商业、质量和功能需求的组合驱动软件架构设计。使用ABSD方法,设计活动可以从项目总体功能框架明确就开始,并且设计活动的开始并不意味着需求抽取和分析活…...
Node.js入门html,css,js 30年了nodejs环境 09年出现 15
Node.js入门 html,css,js 30年了 nodejs环境 09年出现 15年 nodejs为我们解决了2个方面的问题: 【锦上添花】让我们前端工程师拥有了后端开发能力(开接口,访问数据库) - 大公司BFF(50)【✔️】前端工程…...
2025跨年倒计时
<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2025年跨年倒计时</title><style>/* 页…...
淘宝京东电商商品SKU信息抓取API测试实战指南
在电商平台的商品管理中,SKU(Stock Keeping Unit,库存单位)信息扮演着至关重要的角色。它不仅关乎商品的库存管理,还直接影响到消费者的购买决策。为了高效地获取并验证电商平台(如淘宝、京东)上…...
SAP财务凭证的更改、冲销的方式
文章目录 一、财务凭证更改二、财务凭证冲销 【SAP系统研究】 #SAP #FICO #SAP财务 一、财务凭证更改 (1)已经过账的财务凭证 FB02:过完帐的允许更改的地方有限,只有凭证抬头文本、参照、分配、文本、原因代码等。 ࿰…...
RepPoints: Point Set Representation for Object Detection
CornerNet论文阅读整理-CSDN博客 可变形卷积(Deformable Conv)原理解析与torch代码实现-CSDN博客 RepPoints(本质是可变形卷积DCN)再理解-CSDN博客 简介: 时间:2019 会议:ICCV 作者:Ze Yang,Shaohui Liu,…...
高效使用AI完成编程项目任务的指南:从需求分析到功能实现
随着人工智能工具的普及,即便是零编程基础或基础薄弱的用户,也可以借助AI完成许多技术任务。然而,要高效地使用AI完成编程任务,关键在于如何清晰表达需求,并逐步引导AI实现目标。 在本文中,我们将通过开发…...
Linux命令——RPM与yum
文章目录 一、RPM包命令1.安装和升级包2.删除包3.查询包信息4.验证和检查5.其他操作 二、yum安装器1.安装包2.更新包3.卸载包4.查询和搜索5.清理缓存6.其他操作 一、RPM包命令 1.安装和升级包 命令解释rpm -ivh package.rpm安装一个 RPM 包,显示详细信息和进度条r…...
C++软件设计模式之责任链模式
责任链模式的动机与意图 动机: 在软件开发中,经常会遇到需要处理一系列请求或事件的情况。这些请求可能需要经过多个处理对象,每个对象根据其职责决定是否处理请求或将其传递给下一个对象。责任链模式(Chain of Responsibility P…...
Spring Cloud Security集成JWT 快速入门Demo
一、介绍 JWT (JSON Web Token) 是一种带有绑实和信息的简单标准化机制,在信息通信中用于验证和信息传递。尤其在应用中使用Spring Cloud实现分布式构建时,JWT可以作为一种无状态验证原理的证明。 本文将进一步描述如何在Spring Cloud Security中集成JW…...
Python 爬虫
一、创建项目 1.双击打开pycharm,点击新建项目 2.项目设置- 勾选[继承全局站点软件包]- 勾选[可用于所有项目]- 取消勾选[创建main.py欢迎脚本]- 点击创建 3.项目名称右键--新建--python文件 4.输入文件名--回车二、编辑代码 # 导入请求模块 import requests # 如…...
【PCIe 总线及设备入门学习专栏 4.1 -- PCI 总线的地址空间分配】
文章目录 Overview 本文转自:https://blog.chinaaet.com/justlxy/p/5100053219 Overview PCI 总线具有32位数据/地址复用总线,所以其存储地址空间为 2324GB。也就是PCI上的所有设备共同映射到这4GB上,每个PCI设备占用唯一的一段PCI地址&…...
虚拟电厂搭建指南:绿虫仿真设计软件的助力
在虚拟电厂的搭建中,绿虫仿真设计软件起着重要作用。 绿虫光伏仿真软件是一款综合性辅助工具,能为虚拟电厂中的光伏项目提供精准数据支持。它所提供的项目选址地气象数据,涵盖海拔、辐照、风速、温度等,数据源为 Meteonorm &…...
开源漏洞管理工具--Faraday
前言 在现代安全领域,面临着两个主要的挑战:一是设计出智能化的方式来获取新信息,二是有效地跟踪和管理发现的内容,以便不断改善修复工作。为了解决这些问题,Faraday应运而生,它能够帮助您专注于漏洞的发现…...
一、EF框架的Database First开发模式(数据库优先)
Database First开发模式(数据库优先) Database First是Entity Framework(EF)的三种开发模式之一,适用于在已有数据库的情况下进行开发。其核心思想是从现有数据库中逆向生成实体类和映射文件,然后在此基础上进行开发。 官方…...
Datawhale AI冬令营(第二期)动手学AI Agent task2--学Prompt工程,优化Agent效果
目录 如何写好Prompt? 工具包神器1:Prompt框架——CO-STAR 框架 工具包神器2:Prompt结构优化 工具包神器3:引入案例 案例:构建虚拟女友小冰 1. 按照 CO-STAR框架 梳理目标 2. 撰写Prompt 3. 制作对话生成应用&…...
Go IO之文件处理,TCPUDP讲解
文章目录 1 文件处理1.1 打开和关闭文件1.2 读取文件1.2.1 简单示例1.2.2 中文乱码1.2.2.1 bufio1.2.2.2 ioutil 1.3 写入文件1.3.1 Write 和 WriteString1.3.2 fmt.Fprintln1.3.2.1 写入文件1.3.2.2 写入标准输出 1.3.3 bufio.NewWriter1.3.4 ioutil.WriteFile 2 TCP&UDP2…...
[卫星遥感] 解密卫星目标跟踪:挑战与突破的深度剖析
目录 [卫星遥感] 解密卫星目标跟踪:挑战与突破的深度剖析 1. 卫星目标跟踪的核心挑战 1.1 目标的高速与不确定性 1.2 卫星传感器的局限性 1.3 数据处理与融合问题 1.4 大尺度与实时性要求 2. 当前卫星目标跟踪的主流技术 2.1 卡尔曼滤波(Kalman …...
U盘提示格式化?原因、恢复方案与预防措施全解析
一、U盘提示格式化现象概述 在日常使用U盘的过程中,我们有时会遇到一个令人头疼的问题——U盘插入电脑后,系统却弹出一个提示框,告知我们U盘需要格式化才能访问。这个提示往往伴随着数据的潜在丢失风险,让我们不禁为之心焦。U盘提…...
Vuex中dispatch的用法
在 Vuex 中,dispatch 是用于触发 actions 的方法,它的主要作用是调用一个 action 并可以传递一些参数。以下是关于 dispatch 的详细解释: 基本语法 dispatch(type, payload)type:要调用的 action 的名称,它是一个字符…...
Agent系列:AppAgent v2-屏幕智能Agent(详解版)
引言 简介 方法 Agent 框架 Agent 交互 探索阶段 部署阶段 文档生成 高级功能 实验结果 总结 局限性 未来工作 1. 引言 大语言模型(LLM)如 ChatGPT 和 GPT-4 显著提升了自然语言处理能力,并且推动了智能体在自主决策中的应用。…...
Word如何插入图片并移动到某个位置
Word如何插入图片并移动到某一个位置 新建word→插入→图片 选择合适的位置→选择图片→打开 点击图片→布局选项→选择文字环绕下的任意一个→固定在页面上 点击图片就可以将图片移动到任意位置...
[CTF/网络安全] 攻防世界 upload1 解题详析
姿势 在txt中写入一句话木马<?php eval($_POST[qiu]);?> 回显如下: 查看源代码: Array.prototype.contains function (obj) { var i this.length; while (i--) { if (this[i] obj) { return true; } } return false; } function …...
golang:微服务架构下的日志追踪系统(二)
背景 在使用Gin框架进行服务开发时,我们遇到了一个日志记录的问题。由于Gin的上下文(*gin.Context)实现了context.Context接口,在调用日志记录器的Info、Warn、Error等方法时,直接传递Gin的上下文通常不会导致编译错误…...
单片机的存储器类型
单片机(Microcontroller Unit, MCU)是一种将计算机的主要部分集成在一个芯片上的微型计算机。它集成了处理器(CPU)、存储器、输入输出接口等必要的功能模块,广泛应用于各种嵌入式系统中。单片机的存储器结构对于理解和使用单片机至关重要&…...
深入剖析MySQL数据库架构:核心组件、存储引擎与优化策略(一)
sql语句分为两大类:查询(select)、增删改----修改(update) select语句的执行流程 执行sql语句的流程:连接数据库、缓存查询、解析器、优化器、执行器、存储引擎操作数据 客户端:图形界面工具…...
java常见的面试题
目录 一、 spring的配置文件的哪四处? 1.数据源(Data Source)配置 2.事务管理器(Transaction Manager)配置 3. 扫描组件(Component Scanning)配置 4. AOP(面向切面编程)配置&…...
2025吉林大学软件学院研究生人工智能原理真题
选择题 5题共10分 5.以下模型不需要训练过程的是? A.支持向量机 B.决策树 C.KNN近邻算法 D.卷积神经网络 简答题 4题35分 1.大模型是否已经通过图灵测试 2.三个近二十年来的机器学习模型和应用案例 3.LDA原理和算法流程 4.CNN原理和算法流程 证明题 谓词逻辑15…...
Qt判别不同平台操作系统调用相应动态库读取RFID
本示例使用的读卡器:https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1b8jdyXi&ftt&id562957272162 #include <QDebug> #include "mainwindow.h" #include "./ui_mainwindow.h" #include "QLibrary"…...
智慧工地系统:建筑施工智能化管理的全新模式
智慧工地概述 智慧工地是将互联网的理念和和物联网的技术引入建筑工地,依托物联网、互联网、大数据、5G技术,建立云端数据平台,形成大数据的业务体系,打通一线操作与远程监管的链条,实现劳务、安全、环境、材料等各个…...
js将object整个实体对象作为参数传递
①将object实体转化成json字符串传递: JSON.stringify(obj) ②将json字符串转化成JSON对象值:JSON.parse(json) 实际应用: <div id"div_notice" stylefont-size:14px; width:100%; height:200px; overflow-y:auto;></di…...
shell的循环结构
1、思维导图 2、定义一个find函数,查找ubuntu和root的gid并使用变量接收结果 #!/bin/bash #第二题查找gid并返回结果 find() {u_gidid -g ubuntur_gidid -g rootecho "root-gid$r_gid"echo "ubuntu-gid$u_gid" } ret$(find) echo $ret3、定义一…...
STM32-笔记29-蓝牙遥控插座项目
一、实验前期准备 手机通过蓝牙模块远程遥控风扇。(插座的原理就是继电器,所以控制继电器就是控制插座电源) 二、项目实现 复制项目文件夹32-蓝牙模块实现,重命名33-蓝牙遥控插座项目 找到一个继电器项目,把继电器复…...
计算机网络复习(习题)
术语辨析 数据链路层 该层在两个通信实体之间传送以帧为单位的数据,通过差错控制方法,使有差错的物理线路变成无差错数据链路。 网络层 负责使分组以适当的路径通过通信子网的层次。 运输层 负责向两台主机中进程之间的通信提供通用的数据传输服务的层次。 应用层…...
webserver的http实现
1、用了状态机,为什么要用状态机? 在逻辑处理模块中,响应的http请求采用主从状态机完成, 传统的控制流程都是按照顺序执行的,状态机能够处理任意顺序的事件,并能提供有意义的响应--即使这些事件发生的顺序和…...
C语言----指针
目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结: 段错误 指针修饰 1. con…...
Elasticsearch与数据库数据一致性:最佳实践与解决方案
在现代应用程序中,Elasticsearch(ES)作为一个高效的分布式搜索引擎,常常与数据库一同使用,以提供强大的搜索、分析和数据可视化功能。然而,数据库和Elasticsearch之间的同步与一致性常常成为一个挑战。如何…...
C# 基本语法
C# 基本语法 介绍 C#(读作 "C sharp")是一种现代的、面向对象的编程语言,由微软开发,并在2000年首次发布。它是.NET框架的一部分,被广泛用于开发各种类型的应用程序,包括桌面应用、Web应用、移…...
CDGA|浅析自动化对数据治理的深远影响
在数字化时代,数据治理已成为企业管理的核心议题之一。随着数据量的快速增长和复杂性的不断提升,传统的手工数据管理方式已难以满足企业的需求。而自动化技术的引入,为数据治理带来了新的动力,正在逐步改变数据治理的面貌。 自动化…...
【机器学习】【朴素贝叶斯分类器】从理论到实践:朴素贝叶斯分类器在垃圾短信过滤中的应用
🌟 关于我 🌟 大家好呀!👋 我是一名大三在读学生,目前对人工智能领域充满了浓厚的兴趣,尤其是机器学习、深度学习和自然语言处理这些酷炫的技术!🤖💻 平时我喜欢动手做实…...
小程序租赁系统的优势与应用探索
内容概要 小程序租赁系统,听起来很高大上,但实际上它比你想象的要实用得多!设想一下,几乎所有的租赁需求都能通过手机轻松解决。这种系统的便捷性体现在让用户随时随地都能发起租赁请求,而不再受制于传统繁琐的手续。…...
汇编环境搭建
学习视频 将MASM所在目录 指定为C盘...
ubuntu24.04使用open-vm-tools无法在主机和虚拟机之间拖拽文件夹
最近安装了vmware用ubuntu24.04作为虚拟机 然后发现无法在主机和虚拟机之间复制粘贴 然后安装了 sudo apt-get install open-vm-tools-desktop重启虚拟机,发现可以复制粘贴文字,但是文件和文件夹仍然不行 搜索发现是Ubuntu(22.04࿰…...
C++软件设计模式之模板方法模式
模板方法模式是面向对象软件设计模式之一,其主要意图是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。 动机 在软件开发中,常常会遇到这样的情…...
20241231 机器学习ML -(2)KNN(scikitlearn)
1. build DKTree 递推创建Tree;当前维度找中位数分割 数据集 left set,Node(mid), right set. * 循环维度(当log(Nsample)>featureSize) 2. DKTree KNN search * 理论部分向量几何有介绍。 每个维度列中,中位数对应的数据点…...