C# 设计模式的七大原则详解

news/2024/11/16 11:31:59/

文章目录

  • 前言
  • 1. 单一职责原则 (SRP)
  • 2. 开放封闭原则 (OCP)
  • 3. 里氏替换原则 (LSP)
  • 4. 依赖倒置原则 (DIP)
  • 5. 接口隔离原则 (ISP)
  • 6. 合成/聚合复用原则 (CARP)
  • 7. 迪米特法则 (LoD)


前言

在 C# 编程中,设计模式的七大原则是保证代码质量和可维护性的基石。这些原则不仅仅是理论上的指导,更是在实际项目开发中的重要实践。本文将详细解释每个原则,并附上相应的 C# 示例代码,帮助读者更好地理解和应用这些原则。


1. 单一职责原则 (SRP)

单一职责原则要求一个类应该只有一个引起变化的原因,即一个类只负责一项功能。这有助于保持类的简洁性和可维护性,降低代码的复杂度。

示例代码:

using System;// 不好的设计,一个类负责了两个不同的功能
class BadDesign
{public void ProcessData(){// 处理数据的逻辑}public void GenerateReport(){// 生成报告的逻辑}
}// 好的设计,将功能分开到不同的类中
class DataProcessor
{public void ProcessData(){// 处理数据的逻辑}
}class ReportGenerator
{public void GenerateReport(){// 生成报告的逻辑}
}

2. 开放封闭原则 (OCP)

开放封闭原则要求软件实体应该对扩展开放,对修改关闭。这意味着通过扩展已有的代码来实现新的功能,而不是修改已有的代码。

示例代码:

using System;// 不好的设计,需要修改原有类来添加新功能
class BadDesign
{public void ProcessData(){// 处理数据的逻辑}
}// 好的设计,通过扩展来添加新功能
interface IDataProcessor
{void ProcessData();
}class DataProcessor : IDataProcessor
{public void ProcessData(){// 处理数据的逻辑}
}class NewFeatureProcessor : IDataProcessor
{public void ProcessData(){// 新功能的处理逻辑}
}

3. 里氏替换原则 (LSP)

里氏替换原则要求子类型必须能够替换掉它们的父类型,确保子类可以完全替代父类,并且不会影响系统的正确性。

示例代码:

using System;// 不好的设计,子类修改了父类的行为
class BadDesign
{public virtual void ProcessData(){// 处理数据的逻辑}
}class Child : BadDesign
{public override void ProcessData(){// 修改了父类的行为}
}// 好的设计,子类不修改父类的行为
class GoodDesign
{public void ProcessData(){// 处理数据的逻辑}
}class Child : GoodDesign
{// 不需要重写父类的方法
}

4. 依赖倒置原则 (DIP)

依赖倒置原则要求高层模块不应该依赖于低层模块,二者都应该依赖于抽象。这有助于降低模块之间的耦合度。

示例代码:

using System;// 不好的设计,高层模块直接依赖于低层模块
class BadDesign
{private LowLevelDependency dependency = new LowLevelDependency();
}class LowLevelDependency
{// 低层模块的功能实现
}// 好的设计,高层模块依赖于抽象
interface IDependency
{void DoSomething();
}class GoodDesign
{private IDependency dependency;public GoodDesign(IDependency dependency){this.dependency = dependency;}
}class LowLevelDependency : IDependency
{public void DoSomething(){// 功能实现}
}

5. 接口隔离原则 (ISP)

接口隔离原则要求客户端不应该被迫依赖于它们不使用的接口,避免接口过于庞大、臃肿。

示例代码:

using System;// 不好的设计,一个接口包含了多个不相关的方法
interface IBadInterface
{void Method1();void Method2();void Method3();
}// 好的设计,根据客户端的需求定义专门的接口
interface IGoodInterface1
{void Method1();
}interface IGoodInterface2
{void Method2();
}

6. 合成/聚合复用原则 (CARP)

合成/聚合复用原则要求尽量使用合成/聚合,而不是继承来实现代码复用,以避免继承带来的紧耦合和继承链的脆弱性。

示例代码:

using System;// 不好的设计,使用继承来复用代码
class BadDesign
{// 共享的逻辑
}class Child : BadDesign
{// 子类的特定逻辑
}// 好的设计,使用组合来复用代码
class GoodDesign
{private SharedLogic sharedLogic;public GoodDesign(SharedLogic sharedLogic){this.sharedLogic = sharedLogic;}
}

7. 迪米特法则 (LoD)

迪米特法则要求一个对象应该对其他对象有尽可能少的了解,避免类之间的直接通信,降低耦合度。

示例代码:

using System;// 不好的设计,类直接依赖于其他类
class BadDesign
{private Dependency dependency = new Dependency();public void DoSomething(){// 使用 dependency 的功能}
}// 好的设计,通过中介者来减少直接依赖
class GoodDesign
{private Mediator mediator;public GoodDesign(Mediator mediator){this.mediator = mediator;}public void DoSomething(){mediator.DoSomething();}
}class Mediator
{private Dependency dependency = new Dependency();public void DoSomething(){// 使用 dependency 的功能}
}

以上是 C# 设计模式的七大原则的详细解释和示例代码。通过遵循这些原则,我们可以编写出更加灵活、可维护和易扩展的代码,从而提高软件开发的效率和质量。


http://www.ppmy.cn/news/1423092.html

相关文章

代码随想录算法训练营第四十三天| 1049. 最后一块石头的重量 II,494. 目标和,474.一和零

题目与题解 1049. 最后一块石头的重量 题目链接:1049. 最后一块石头的重量 代码随想录题解:1049. 最后一块石头的重量 视频讲解:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重…

Python-Qt上位机设计

1.下载designer软件 2.自己设计一个界面 3.在指定部件加入点击响应命令函数名 鼠标点击目标部件拖出信号线 4.保存生成.ui文件,用pycharm打开 5.生成.py文件 6.新建一个功能文件 上图中class MainWindow的具体代码不予展示。 7.生成exe文件 将写好的py文件保存&a…

【练习】二分查找思想

🎥 个人主页:Dikz12🔥个人专栏:算法(Java)📕格言:吾愚多不敏,而愿加学欢迎大家👍点赞✍评论⭐收藏 目录 二分查找算法介绍 1.二分查找 题目描述 讲解 ​编辑 代码实现 2.…

在 Vue中,v-for 指令的使用

在 Vue中&#xff0c;v-for 指令用于渲染一个列表&#xff0c;基于源数据多次渲染元素或模板块。它对于展示数组或对象中的数据特别有用。 数组渲染 假设你有一个数组&#xff0c;并且你想为每个数组元素渲染一个 <li> 标签&#xff1a; <template> <ul>…

STM32应用开发——BH1750光照传感器详解

STM32应用开发——BH1750光照传感器详解 目录 STM32应用开发——BH1750光照传感器详解前言1 硬件介绍1.1 BH1750简介1.2 硬件接线 2 软件编程2.1 软件原理2.1.1 IIC设备地址2.1.2 IIC读写2.1.3 BH1750指令集2.1.4 BH1750工作流程2.1.5 BH1750测量模式 2.2 测试代码2.3 运行测试…

反转二叉树(力扣226)

解题思路&#xff1a;用队列进行前序遍历的同时把节点的左节点和右节点交换 具体代码如下&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if (root NULL) return root;swap(root->left, root->right); // 中invertTree(root->left)…

2024.4.13力扣每日一题——找到冠军 II

2024.4.13 题目来源我的题解方法一 拓扑排序思想 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2924 我的题解 方法一 拓扑排序思想 计算每个节点的入度&#xff0c;只有入度为0的节点才可能是冠军&#xff0c;但是若存在多个入度为0的节点&#xff0c;则无法知道谁是…

Andorid dumpsys battery获取电池信息

dumpsys battery 未充电 console:/ # dumpsys battery Current Battery Service state:AC powered: falseUSB powered: falseWireless powered: falseMax charging current: 0Max charging voltage: 0Charge counter: 1…