C#中常见的软件设计模式及应用场景
文章目录
- 前言
- 1、单例模式 (Singleton)
- 1.1 详细说明
- 1.2 应用场景示例
- 2、工厂模式 (Factory Method)
- 2.1 详细说明
- 2.2 应用场景示例
- 3、观察者模式 (Observer)
- 3.1 详细说明
- 3.2 应用场景示例
- 4、策略模式 (Strategy)
- 4.1 详细说明
- 4.2 应用场景示例
- 5、适配器模式 (Adapter)
- 5.1 详细说明
- 5.2 应用场景示例
- 总结
前言
在C#开发中,设计模式是一种被广泛应用的软件设计思想,它可以帮助我们提高代码的可维护性、可扩展性和可复用性。本文将详细介绍C#中几种常见的软件设计模式,并提供每种模式的具体应用场景示例,以展示其在实际项目中的应用效果和益处。
1、单例模式 (Singleton)
1.1 详细说明
单例模式确保一个类只有一个实例,并提供一个全局访问点。这个模式通常用于那些只需要一个实例且频繁使用的对象,例如数据库连接池、日志对象、配置对象等。
1.2 应用场景示例
场景1: 应用程序需要一个全局的配置管理器来管理所有的配置信息。
public class ConfigurationManager
{private static ConfigurationManager _instance;private ConfigurationManager(){// 初始化配置}public static ConfigurationManager Instance{get{if (_instance == null){_instance = new ConfigurationManager();}return _instance;}}// 配置操作方法
}
场景2: 在一个多线程的环境下,需要确保某个资源只被创建一次并在全局范围内访问。比如数据库连接池的实现。
public class Singleton
{private static Singleton instance;private static readonly object lockObject = new object();private Singleton() { }public static Singleton Instance{get{lock (lockObject){if (instance == null){instance = new Singleton();}}return instance;}}
}
2、工厂模式 (Factory Method)
2.1 详细说明
工厂模式定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类中进行。
2.2 应用场景示例
场景: 应用程序需要根据用户的选择创建不同类型的图形对象(如圆形、矩形)。
public interface IGraphic
{void Draw();
}public class Circle : IGraphic
{public void Draw(){Console.WriteLine("Drawing a circle");}
}public class Rectangle : IGraphic
{public void Draw(){Console.WriteLine("Drawing a rectangle");}
}public abstract class Factory
{public abstract IGraphic CreateGraphic(string type);
}public class CircleFactory : Factory
{public override IGraphic CreateGraphic(string type){return new Circle();}
}public class RectangleFactory : Factory
{public override IGraphic CreateGraphic(string type){return new Rectangle();}
}// 使用
IFactory factory = new CircleFactory();
IGraphic graphic = factory.CreateGraphic("Circle");
graphic.Draw(); // 输出: Drawing a circle
3、观察者模式 (Observer)
3.1 详细说明
观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。
3.2 应用场景示例
场景1: 股票市场应用程序中,当股票价格发生变化时,需要通知所有订阅了该股票的投资者。
public interface IObserver
{void Update(float stockPrice);
}public interface ISubject
{void Attach(IObserver observer);void Detach(IObserver observer);void Notify();
}public class StockMarket : ISubject
{private List<IObserver> observers = new List<IObserver>();private float stockPrice;public void Attach(IObserver observer){observers.Add(observer);}public void Detach(IObserver observer){observers.Remove(observer);}public void Notify(){foreach (var observer in observers){observer.Update(stockPrice);}}public void SetStockPrice(float price){stockPrice = price;Notify();}
}public class Investor : IObserver
{public void Update(float stockPrice){Console.WriteLine($"Stock price updated to: {stockPrice}");}
}// 使用
StockMarket stockMarket = new StockMarket();
Investor investor1 = new Investor();
Investor investor2 = new Investor();stockMarket.Attach(investor1);
stockMarket.Attach(investor2);stockMarket.SetStockPrice(100.0f); // 两个投资者都将收到通知
场景2: 在一个新闻发布订阅系统中,当有新的新闻发布时,订阅者可以自动收到通知并显示最新的新闻内容。
public interface IObserver
{void Update(string news);
}public interface ISubject
{void Attach(IObserver observer);void Detach(IObserver observer);void Notify(string news);
}public class NewsPublisher : ISubject
{private List<IObserver> observers = new List<IObserver>();private string news;public void Attach(IObserver observer){observers.Add(observer);}public void Detach(IObserver observer){observers.Remove(observer);}public void Notify(string news){this.news = news;foreach (var observer in observers){observer.Update(news);}}
}public class NewsSubscriber : IObserver
{private string name;public NewsSubscriber(string name){this.name = name;}public void Update(string news){Console.WriteLine($"{name} received news: {news}");}
}
4、策略模式 (Strategy)
4.1 详细说明
策略模式定义了一系列算法,并将每一个算法封装起来,以便它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。
4.2 应用场景示例
场景: 一个文本编辑器需要支持多种格式的文件保存方式(如纯文本、HTML、Markdown等)。
public abstract class FileSaverStrategy
{public abstract void Save(string content, string filePath);
}public class TextFileSaver : FileSaverStrategy
{public override void Save(string content, string filePath){using (StreamWriter sw = File.CreateText(filePath)){sw.Write(content);}}
}public class HtmlFileSaver : FileSaverStrategy
{public override void Save(string content, string filePath){// HTML 保存逻辑}
}public class MarkdownFileSaver : FileSaverStrategy
{public override void Save(string content, string filePath){// Markdown 保存逻辑}
}public class Document
{private FileSaverStrategy saver;public void SetSaver(FileSaverStrategy saver){this.saver = saver;}public void SaveDocument(string content, string filePath){saver.Save(content, filePath);}
}// 使用
Document document = new Document();
document.SetSaver(new TextFileSaver());
document.SaveDocument("Hello, World!", "hello.txt");// later on, if we want to save as HTML
document.SetSaver(new HtmlFileSaver());
document.SaveDocument("<p>Hello, World!</p>", "hello.html");
5、适配器模式 (Adapter)
5.1 详细说明
适配器模式将一个类的接口转换成客户端期望的另一个接口。适配器模式让原本接口不兼容的类可以一起工作。
5.2 应用场景示例
场景: 有一个旧式的音乐播放器,只能播放MP3格式的音乐,但现在需要播放MP4格式的音乐。
public interface IMusicPlayer
{void Play(string fileExtension);
}public class Mp3MusicPlayer : IMusicPlayer
{public void Play(string fileExtension){if (fileExtension == "mp3"){Console.WriteLine("Playing MP3 music");}}
}public class Mp4MusicPlayer : IMusicPlayer
{public void Play(string fileExtension){if (fileExtension == "mp4"){Console.WriteLine("Playing MP4 music");}}
}public class Mp4ToMp3Adapter : IMusicPlayer
{private Mp4MusicPlayer mp4Player;public Mp4ToMp3Adapter(Mp4MusicPlayer mp4Player){this.mp4Player = mp4Player;}public void Play(string fileExtension){if (fileExtension == "mp3"){// 将MP4音乐转换为MP3音乐mp4Player.Play("mp4");}}
}// 使用
IMusicPlayer musicPlayer = new Mp3MusicPlayer();
musicPlayer.Play("mp3"); // 输出:Playing MP3 musicmusicPlayer = new Mp4ToMp3Adapter(new Mp4MusicPlayer());
musicPlayer.Play("mp3"); // 输出:Playing MP4 music(通过适配器转换)
总结
通过使用这些常见的设计模式,我们可以更好地组织和管理代码,提高代码的可读性、可维护性和可扩展性。每个设计模式都有其独特的应用场景和优势,在实际项目中灵活运用可以有效解决各种问题。希望本文能够帮助读者理解C#设计模式的多样性,并在实践中加以应用。
相关文章:
C#中常见的软件设计模式及应用场景
文章目录 前言1、单例模式 (Singleton)1.1 详细说明1.2 应用场景示例 2、工厂模式 (Factory Method)2.1 详细说明2.2 应用场景示例 3、观察者模式 (Observer)3.1 详细说明3.2 应用场景示例 4、策略模式 (Strategy)4.1 详细说明4.2 应用场景示例 5、适配器模式 (Adapter)5.1 详细…...
字符串相关函数和文件操作
文章目录 1. C/C 字符串概述1.1 字符串常量1.2 字符数组 2. 字符串函数2.1 拷贝赋值功能相关函数(覆盖)2.1.1 strcpy2.1.2 strncpy2.1.3 memcpy2.1.4 memmove2.1.5 memset2.1.6 注意小点2.1.7 【函数区别】 2.2 追加功能相关函数2.2.1 strcat2.2.2 strnc…...
【c++学习】数据结构中的栈
c栈 栈代码用线性表实现栈用链表实现栈 栈 栈:先进后出 只对栈顶元素进行操作,包括新元素入栈、栈顶元素出栈和查看栈顶元素(只支持对栈顶的增、删、查)。 代码 下述代码实现了栈及其接口 包括对栈顶的增、删、查以及查看栈的大…...
新建react项目,react-router-dom配置路由,引入antd
提示:reactrouter6.4版本,与reactrouter5.0的版本用法有区别,互不兼容需注意 文章目录 前言一、创建项目二、新建文件并引入react-router-dom、antd三、配置路由跳转四、效果五、遇到的问题六、参考文档总结 前言 需求:新建react项…...
Transformer and Pretrain Language Models3-6
Pretrain Language Models预训练语言模型 content: language modeling(语言模型知识) pre-trained langue models(PLMs)(预训练的模型整体的一个分类) fine-tuning approaches GPT and BERT(…...
Linux系统中编写bash脚本进行mysql的数据同步
一、为何要用脚本做数据同步 (一)、问题 我们的视频监控平台云服务器,需要向上级的服务器定期同步一些数据表的数据,前期做了个程序,可以实现同步。但是,现在数据库的结构改了,结果又需要该程序…...
光耦驱动继电器电路图大全
光耦驱动继电器电路图(一) 注: 1U1-1脚可接12V,也可接5V,1U1导通,1Q1导通,1Q1-30V,线圈两端电压为11.7V. 1U1-1脚不接或接地,1U1不通,1Q1截止,1…...
【AI量化分析】小明在量化中使用交叉验证原理深度分析解读
进行交叉验证好处 提高模型的泛化能力:通过将数据集分成多个部分并使用其中的一部分数据进行模型训练,然后使用另一部分数据对模型进行测试,可以确保模型在未见过的数据上表现良好。这样可以降低模型过拟合或欠拟合的风险,提高模…...
2024最新版Visual Studio Code安装使用指南
2024最新版Visual Studio Code安装使用指南 Installation and Usage Guide for the Latest Visual Studio Code in 2024 By JacksonML Visual Studio Code最新版1.85已经于2023年11月由其官网 https://code.visualstudio.com正式发布,这是微软公司2024年发行的的最…...
接口请求重试八种方法
请求三方接口需要加入重试机制 一、循环重试 在请求接口的代码块中加入循环,如果请求失败则继续请求,直到请求成功或达到最大重试次数。 int retryTimes 3; for(int i 0;i < retryTimes;i){try{//请求接口的代码break;}catch(Exception e){//处理…...
【Linux 基础】常用基础指令(上)
文章目录 一、 创建新用户并设置密码二、ls指令ls指令基本概念ls指令的简写操作 三、pwd指令四、cd指令五、touch指令六、rm指令七、mkdir指令八、rmdir 指令 一、 创建新用户并设置密码 ls /home —— 查看存在多少用户 whoami —— 查看当前用户名 adduser 用户名 —— 创建新…...
【RT-DETR有效改进】EfficientFormerV2移动设备优化的视觉网络(附对比试验效果图)
前言 大家好,我是Snu77,这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进,内容持续更新,每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本,同时修改内容也支持Re…...
《动手学深度学习(PyTorch版)》笔记4.4
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过。…...
Linux/Academy
Enumeration nmap 首先扫描目标端口对外开放情况 nmap -p- 10.10.10.215 -T4 发现对外开放了22,80,33060三个端口,端口详细信息如下 结果显示80端口运行着http,且给出了域名academy.htb,现将ip与域名写到/et/hosts中,然后从ht…...
windows .vscode的json文件配置 CMake 构建项目 调试窗口中文设置等
一、CMake 和 mingw64的安装和环境配置 二、tasks.json和launch.json文件配置 tasks.json {"version": "2.0.0","options": {"cwd": "${workspaceFolder}/build"},"tasks": [{"type": "shell&q…...
uniapp canvas做的刮刮乐解决蒙层能自定义图片
最近给湖南中烟做元春活动,一个月要开发4个小活动,这个是其中一个难度一般,最难的是一个类似鲤鱼跃龙门的小游戏,哎,真实为难我这个“拍黄片”的。下面是主要代码。 <canvas :style"{width:widthpx,height:hei…...
利用SPI,结合数据库连接池durid进行数据服务架构灵活设计
接着上一篇文章业务开始围绕原始凭证展开,而展开的基础无疑是围绕着科目展开的。首先我们业务层面以财政部的小企业会计准则的一级科目引入软件中。下面我们来考虑如何将科目切入软件更加灵活,方便业务扩展、维护与升级。 SPI是首先想到的数据服务方式 为什么会想到它呢?首…...
自动驾驶的决策层逻辑
作者 / 阿宝 编辑 / 阿宝 出品 / 阿宝1990 自动驾驶意味着决策责任方的转移 我国2020至2025年将会是向高级自动驾驶跨越的关键5年。自动驾驶等级提高意味着对驾驶员参与度的需求降低,以L3级别为界,低级别自动驾驶环境监测主体和决策责任方仍保留于驾驶…...
排序算法——希尔排序算法详解
希尔排序算法详解 一. 引言1. 背景介绍1.1 数据排序的重要性1.2 希尔排序的由来 2. 排序算法的分类2.1 比较排序和非比较排序2.2 希尔排序的类型 二. 希尔排序基本概念1. 希尔排序的定义1.1 缩小增量排序1.2 插入排序的变种 2. 希尔排序的工作原理2.1 分组2.2 插入排序2.3 逐步…...
Docker 容器内运行 mysqldump 命令来导出 MySQL 数据库,自动化备份
备份容器数据库命令: docker exec 容器名称或ID mysqldump -u用户名 -p密码 数据库名称 > 导出文件.sql请替换以下占位符: 容器名称或ID:您的 MySQL 容器的名称或ID。用户名:您的 MySQL 用户名。密码:您的 MySQL …...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
