C# 中常见的设计模式
设计模式是一套被广泛应用于软件设计的最佳实践,它们可以帮助开发者解决特定的问题,提高代码的可重用性、可读性和可维护性。本文将介绍 C#
中常见的几种设计模式,并提供相应的示例代码。
- 工厂模式
工厂模式是一种创建型设计模式,它提供了一种将对象的创建过程与使用过程分离的方式。它通过定义一个工厂类,使得客户端代码可以从工厂类中获取所需的对象,而无需知道对象的具体创建过程。
以下是工厂模式的一个示例:
public interface IProduct
{void DoSomething();
}public class ProductA : IProduct
{public void DoSomething(){Console.WriteLine("ProductA does something.");}
}public class ProductB : IProduct
{public void DoSomething(){Console.WriteLine("ProductB does something.");}
}public class ProductFactory
{public IProduct CreateProduct(string type){switch (type){case "A":return new ProductA();case "B":return new ProductB();default:throw new ArgumentException("Invalid product type");}}
}class Program
{static void Main(string[] args){ProductFactory factory = new ProductFactory();IProduct productA = factory.CreateProduct("A");IProduct productB = factory.CreateProduct("B");productA.DoSomething();productB.DoSomething();Console.ReadKey();}
}
在上面的示例中,我们定义了 IProduct 接口和两个实现类 ProductA 和 ProductB。然后,我们定义了一个工厂类 ProductFactory,它可以根据客户端代码传入的参数创建不同的产品对象。
在客户端代码中,我们实例化了 ProductFactory 并通过它创建了两个不同的产品对象。这种方式可以使得客户端代码不需要知道对象的具体创建过程,从而提高了代码的可重用性和可维护性。
- 单例模式
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了全局访问该实例的方式。
以下是单例模式的一个示例:
public class Singleton
{private static Singleton instance;private Singleton() { }public static Singleton Instance{get{if (instance == null){instance = new Singleton();}return instance;}}public void DoSomething(){Console.WriteLine("Singleton does something.");}
}class Program
{static void Main(string[] args){Singleton singleton = Singleton.Instance;singleton.DoSomething();Console.ReadKey();}
}
在上面的示例中,我们定义了一个 Singleton 类,并通过将构造函数私有化来防止外部直接实例化它。然后,我们定义了一个静态字段 instance,用来保存 Singleton 类的唯一实例。我们还定义了一个静态属性 Instance,通过它来获取 Singleton 类的唯一实例。
在客户端代码中,我们通过 Singleton.Instance 获取 Singleton 类的唯一实例,并调用它的 DoSomething 方法。由于 Singleton 类只有一个实例,因此多次调用 Singleton.Instance 得到的都是同一个实例。
- 观察者模式
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,使得多个观察者对象可以同时监听某个主题对象的状态变化。
以下是观察者模式的一个示例:
public interface IObserver
{void Update(string message);
}public interface ISubject
{void RegisterObserver(IObserver observer);void RemoveObserver(IObserver observer);void NotifyObservers(string message);
}public class Subject : ISubject
{private List<IObserver> observers = new List<IObserver>();public void RegisterObserver(IObserver observer){observers.Add(observer);}public void RemoveObserver(IObserver observer){observers.Remove(observer);}public void NotifyObservers(string message){foreach (IObserver observer in observers){observer.Update(message);}}
}public class Observer : IObserver
{public void Update(string message){Console.WriteLine($"Observer received message: {message}");}
}class Program
{static void Main(string[] args){Subject subject = new Subject();Observer observer1 = new Observer();Observer observer2 = new Observer();subject.RegisterObserver(observer1);subject.RegisterObserver(observer2);subject.NotifyObservers("Hello, observers!");subject.RemoveObserver(observer2);subject.NotifyObservers("Hello again, observers!");Console.ReadKey();}
}
在上面的示例中,我们定义了 IObserver 和 ISubject 接口,分别表示观察者和主题对象。然后,我们实现了 Subject 类,它实现了 ISubject 接口,并提供了注册观察者、移除观察者和通知观察者的方法。我们还实现了 Observer 类,它实现了 IObserver 接口,并在 Update 方法中打印出接收到的消息。
在客户端代码中,我们创建了一个 Subject 对象和两个 Observer 对象,并通过 RegisterObserver 方法将这两个观察者对象注册到 Subject 对象上。然后,我们调用 NotifyObservers 方法,将消息发送给所有注册的观察者对象。最后,我们通过 RemoveObserver 方法移除了一个观察者对象,并再次调用 NotifyObservers 方法发送消息给剩下的观察者对象。
- 策略模式
策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法都封装起来,并且使它们之间可以互换。
以下是策略模式的一个示例:
public interface IStrategy
{void Execute();
}public class StrategyA : IStrategy
{public void Execute(){Console.WriteLine("Strategy A is executed.");}
}public class StrategyB : IStrategy
{public void Execute(){Console.WriteLine("Strategy B is executed.");}
}public class Context
{private IStrategy strategy;public Context(IStrategy strategy){this.strategy = strategy;}public void SetStrategy(IStrategy strategy){this.strategy = strategy;}public void ExecuteStrategy(){strategy.Execute();}
}class Program
{static void Main(string[] args){IStrategy strategyA = new StrategyA();IStrategy strategyB = new StrategyB();Context context = new Context(strategyA);context.ExecuteStrategy();context.SetStrategy(strategyB);context.ExecuteStrategy();Console.ReadKey();}
}
在上面的示例中,我们定义了 IStrategy 接口,表示一个算法的接口。然后,我们实现了两个具体的策略类 StrategyA 和 StrategyB,它们分别实现了 IStrategy 接口。最后,我们定义了 Context 类,它包含一个 IStrategy 类型的字段和一个 ExecuteStrategy 方法,通过它来执行当前策略对象的算法。Context 类还提供了一个 SetStrategy 方法,用于在运行时切换策略对象。
在客户端代码中,我们创建了一个 Context 对象,并将 StrategyA 对象作为它的构造参数。然后,我们调用 ExecuteStrategy 方法,执行 StrategyA 的算法。接着,我们调用 SetStrategy 方法,将策略对象切换为 StrategyB,再次调用 ExecuteStrategy 方法,执行 StrategyB 的算法。
以上是 C# 中几种常见的设计模式以及相应的示例代码。
相关文章:
C# 中常见的设计模式
设计模式是一套被广泛应用于软件设计的最佳实践,它们可以帮助开发者解决特定的问题,提高代码的可重用性、可读性和可维护性。本文将介绍 C# 中常见的几种设计模式,并提供相应的示例代码。 工厂模式 工厂模式是一种创建型设计模式,…...
promethues/servicemonitor
目录 1.promethues 能保证源源不断地采集/metrics 信息吗?每次都是最新的吗 2.部署servicemonitor 的作用是什么? 3.pod 部署采集数据直接上报promthues ,不通过servicemonitor 可以吗? 4.你说的"此外,如果部署…...
postman使用简介
1、介绍 postman是一款功能强大的网页调试和模拟发送HTTP请求的Chrome插件,支持几乎所有类型的HTTP请求 2、下载及安装 官方文档:https://www.getpostman.com/docs/v6/ chrome插件:chrome浏览器应用商店直接搜索添加即可(需墙&…...
@DS注解在事务中实现数据源的切换@DS在事务中失效【已解决】
在Springboot的application.yml中的配置: spring:datasource:url: jdbc:mysql://localhost:3306/test2?serverTimezoneUTC&useUnicodetrue&characterEncodingutf8driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rootdynamic:primar…...
Java I/O之文件系统
一、全文概览 在学习文件系统之前,需要了解下Java在I/O上的发展史:在Java7之前,打开和读取文件需要编写特别笨拙的代码,涉及到很多的InputStream、OutputStream等组合起来使用,每次在使用时或许都需要查一下文档才能记…...
Mysql元数据获取方法(information_schema绕过方法)
前提:如果waf或其它过滤了information_schema关键字,那我们该如何获取元数据呢?能够代替information_schema的有:sys.schema_auto_increment_columnssys.schema_table_statistics_with_bufferx$schema_table_statistics_with_buff…...
Eclipse快捷键
* 1.补全代码的声明:alt /* 2.快速修复: ctrl 1 * 3.批量导包:ctrl shift o* 4.使用单行注释:ctrl /* 5.使用多行注释: ctrl shift / * 6.取消多行注释:ctrl shift \* 7.复制指定行的代码:ctrl a…...
java ssm自习室选座预约系统开发springmvc
人工管理显然已无法应对时代的变化,而自习室选座预约系统开发能很好地解决这一问题,既能提高人力物力,又能提高预约选座的知名度,取代人工管理是必然趋势。 本自习室选座预约系统开发以SSM作为框架,JSP技术,…...
分享我从功能测试转型到测试开发的真实故事
由于这段时间我面试了很多家公司,也经历了之前公司的不愉快。所以我想写一篇文章来分享一下自己的面试体会。希望能对我在之后的工作或者面试中有一些帮助,也希望能帮助到正在找工作的你。 找工作 我们总是草率地进入一个自己不了解的公司工作…...
TypeScript快速入门———(二)TypeScript常用类型
文章目录概述1 类型注解2 常用基础类型概述3.原始类型4 数组类型5 类型别名6.函数类型7 对象类型8 接口9 元组10 类型推论11 类型断言12 字面量类型13 枚举14 any 类型15 typeof概述 TypeScript 是 JS 的超集,TS 提供了 JS 的所有功能,并且额外的增加了…...
Mac M1 使用Centos8➕VMware Fusion进行静态网络配置
大部分的流程网络上面都有当我们已经下载好mac m1版的Centos8链接: https://pan.baidu.com/s/1UTl4Lo-_c17s-PDj3dA6kA 提取码: 7xh2 和VMware Fusionhttps://www.vmware.com/cn/products/fusion.html之后就可以进行安装了在导入过后 记得将硬盘和内存都设置好了 记得在关机状态…...
RadGraph: Extracting Clinical Entities and Relations from Radiology Reports代码
文章来源:NeurIPS 文章类别:IE(Information Extraction) RadGraph主要基于dygie,主要文件为inference.py。 inference.py: 1、get_file_list(data_path) def get_file_list(path):file_list [item for item in glob.glob(f&q…...
13. OPenGL与QT界面元素交互控制图形渲染
1. 说明: 前面文章中讲到的 OPenGL 渲染都是在页面加载完成即立刻渲染的,如果向控制图形渲染的时间,可以在QT界面中添加一些元素来进行控制。此时需要用到OPenGL当中的makeCurrent(),update(),doneCurrent()函数。 效果展示: ope…...
高通平台开发系列讲解(USB篇)libuvc详解
文章目录 一、什么是UVC二、UVC拓扑结构三、libuvc的预览时序图沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍libuvc。 一、什么是UVC UVC,全称为:USB video(device) class。 UVC是微软与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标…...
ICC2:set_route_opt_target_endpoints
route_opt阶段通过指定endpoint/driver pin list的方式执行incremental优化。 set_route_opt_target_endpoints [-setup_endpoints file] [-setup_endpoints_collection pin_list] [-hold_endpoints file] [-hold_endpoints_collection pin_list] [-ldrc_objects fil…...
5、小程序面试题
1, 小程序页面有哪些生命周期函数onLoad: 页面加载onReady: 页面初次渲染完成onShow: 页面显示onHide: 页面隐藏onUnload: 页面卸载2, 一页小程序页面有哪些文件组成,分别有什么作用.wxml: 使用微信框架设计的一套组件构建页面结构.wxss: 用于设置页面样式, 和css基本一致.js :…...
Java特殊操作流
6 特殊操作流 6.1 标注输入输出流 System类中有两个静态的成员变量: public static final InputStream in:标准输入流,通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源public static final PrintStream out:标准输…...
如何用SCRM销售管理系统管理销售和做销售管理
每一家企业都在找适合自己公司的销售管理方法,实现销售目标和努力提高业绩。 我们常说,做好销售管理有很多路径和方法,但我们不知道从哪里开始?每个阶段我们该怎么办?如何有效管理销售团队?好的企企业微信…...
分享117个HTML婚纱模板,总有一款适合您
分享117个HTML婚纱模板,总有一款适合您 117个HTML婚纱模板下载链接:https://pan.baidu.com/s/1cC3I5cfh91-KmQj4nfSoPA?pwd9hod 提取码:9hod Python采集代码下载链接:采集代码.zip - 蓝奏云 import os import shutil import …...
VIVADO2022 sdk 工程创建流程
正点原子uart历程复现 create block design(起名 为System) -> open block design -> 号/IP catalog 中搜索zynq 双击打开, 将和pl相关的时钟都干掉 再auto 布线一下 把herarchy中的sources 中的system.bd右键、 无脑下一步导出 如…...
别再硬编码数据了!用QAbstractTableModel+QTableView打造你的第一个Qt桌面表格应用(附完整源码)
从零构建Qt桌面表格应用:实战学生信息管理系统 在桌面应用开发领域,数据展示与交互一直是核心需求。无论是企业内部的员工管理系统,还是学校里的成绩统计工具,一个高效、美观的表格界面往往能极大提升工作效率。对于C开发者而言&a…...
凌扬微优势代理 LY3508 4.2V/1A充电/1.6A驱动 全桥马达驱动控制芯片 ESOP8 技术解析
在电动牙刷、智能垃圾桶等单节锂电池供电的马达类产品中,需要一款集成锂电池充电管理和全桥马达驱动的芯片,以实现电机正反转、刹车控制,并简化外围电路设计。LY3508是一款集成了锂电池充电管理模块、全桥马达驱动模块、续流二极管和逻辑控制…...
终极AI图层分离指南:如何5分钟内将单张插画转为分层PSD文件
终极AI图层分离指南:如何5分钟内将单张插画转为分层PSD文件 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 你是否曾经面对复杂的插画设计&am…...
GTA5线上小助手:解锁洛圣都无限可能的游戏增强神器
GTA5线上小助手:解锁洛圣都无限可能的游戏增强神器 【免费下载链接】GTA5OnlineTools GTA5线上小助手 项目地址: https://gitcode.com/gh_mirrors/gt/GTA5OnlineTools 你是否曾在《侠盗猎车手5》线上模式中感到力不从心?面对繁琐的任务、漫长的通…...
visionOS开发实战:从示例项目到空间应用构建全指南
1. 从零到一:如何高效利用 visionOS 示例项目库如果你和我一样,是个对 Apple Vision Pro 和 visionOS 开发充满好奇的开发者,那么你肯定经历过这样的阶段:面对一个全新的平台,既兴奋于其无限的可能性,又对如…...
三步搞定B站4K视频下载:从新手到高手的完整指南
三步搞定B站4K视频下载:从新手到高手的完整指南 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 还在为无法离线观看B站精彩…...
【冷链配送】遗传算法求解低碳冷链物流车辆路径问题(目标函数固定成本 运输成本 制冷成本 惩罚成本 总碳排放成本)【含Matlab源码 15428期】
💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab领域博客之家💞&…...
从‘主仆’到‘边沿’:一个硬件工程师眼中的触发器进化史,以及为什么主从结构今天依然值得学
从机械钟摆到量子比特:触发器技术演进中的工程智慧 在数字电路的世界里,触发器如同精密的时间齿轮,默默协调着信息流动的节奏。当我们回溯这段技术发展史,会发现每一次触发器结构的革新都不是偶然的灵感闪现,而是工程…...
基于MCP协议构建本地AI多代理协作平台:Roundtable AI实战指南
1. 项目概述:告别单打独斗,开启AI圆桌会议如果你和我一样,每天在IDE里写代码、调试、优化,那你肯定也经历过这种场景:遇到一个复杂的性能问题,你打开Claude的聊天窗口,把前端错误日志贴进去&…...
PX4 Firmware V1.14.4 开源支持
PX4 官方固件版本迭代迅猛,这往往导致开发者在硬件兼容性、环境搭建及软件依赖性上遭遇重重挑战。为彻底解决这一问题,Kerloud 推出固件与文档长期支持(LTS)计划。我们将对飞控固件代码、技术文档及参数调优指南实施持续性维护&am…...
