C# 一分钟浅谈:设计模式之单例模式
创作时间:
作者:
@小白创作中心
C# 一分钟浅谈:设计模式之单例模式
引用
1
来源
1.
https://developer.aliyun.com/article/1627706
单例模式是软件开发中最简单也是最常用的设计模式之一。它确保一个类只有一个实例,并提供一个全局访问点。本文将从单例模式的基本概念出发,逐步深入探讨其实现方式、常见问题、易错点及如何避免这些问题,并通过代码示例进行详细说明。
单例模式的基本概念
单例模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式通常用于那些需要频繁创建和销毁的对象,或者那些在整个应用程序生命周期中只需要一个实例的对象。
优点
- 资源消耗低:由于整个应用程序中只有一个实例,因此可以节省内存。
- 全局访问:提供了一个全局访问点,方便在任何地方使用该实例。
- 控制共享资源:可以更好地控制对共享资源的访问,例如数据库连接、线程池等。
缺点
- 滥用单例:如果过度使用单例模式,可能会导致代码耦合度增加,难以测试和维护。
- 多线程问题:在多线程环境中,如果不加锁处理,可能会导致多个实例的创建。
单例模式的实现方式
饿汉式(Eager Initialization)
饿汉式是最简单的单例模式实现方式,它在类加载时就创建了实例。这种方式是线程安全的,但可能会浪费资源,因为实例在程序启动时就被创建了,即使不使用也会占用内存。
public class Singleton
{
// 在静态构造函数中创建实例
private static readonly Singleton _instance = new Singleton();
// 私有构造函数,防止外部实例化
private Singleton() {
}
// 提供全局访问点
public static Singleton Instance
{
get {
return _instance; }
}
}
懒汉式(Lazy Initialization)
懒汉式在第一次使用时才创建实例,这种方式可以节省资源,但需要处理多线程问题。
线程不安全的懒汉式
public class Singleton
{
private static Singleton _instance;
private Singleton() {
}
public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
线程安全的懒汉式
public class Singleton
{
private static Singleton _instance;
private static readonly object _lock = new object();
private Singleton() {
}
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}
使用 Lazy 实现线程安全的懒汉式
Lazy
public class Singleton
{
private static readonly Lazy<Singleton> _lazy = new Lazy<Singleton>(() => new Singleton());
private Singleton() {
}
public static Singleton Instance
{
get {
return _lazy.Value; }
}
}
常见问题与易错点
多线程问题
在多线程环境中,如果不加锁处理,可能会导致多个实例的创建。如上所述,可以通过双检锁(Double-Check Locking)或使用 Lazy
序列化问题
在某些情况下,单例对象可能需要被序列化和反序列化。如果直接序列化和反序列化单例对象,可能会导致多个实例的创建。可以通过实现 ISerializable 接口来解决这个问题。
[Serializable]
public class Singleton : ISerializable
{
private static readonly Singleton _instance = new Singleton();
private static readonly object _lock = new object();
private Singleton() {
}
public static Singleton Instance
{
get {
return _instance; }
}
protected Singleton(SerializationInfo info, StreamingContext context)
{
// 反序列化时返回现有的实例
_instance = (Singleton)info.GetValue("Instance", typeof(Singleton));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Instance", _instance);
}
}
反射问题
通过反射,可以在运行时创建私有构造函数的实例,从而破坏单例模式。可以通过在构造函数中添加检查来防止这种情况。
public class Singleton
{
private static readonly Singleton _instance = new Singleton();
private static bool _isInitialized = false;
private Singleton()
{
if (_isInitialized)
{
throw new InvalidOperationException("Singleton instance already created.");
}
_isInitialized = true;
}
public static Singleton Instance
{
get {
return _instance; }
}
}
总结
单例模式是一种简单但强大的设计模式,适用于需要全局唯一实例的场景。通过本文的介绍,我们了解了单例模式的基本概念、实现方式、常见问题及解决方案。希望这些内容能帮助你在实际开发中更好地应用单例模式,提高代码的质量和可维护性。
热门推荐
政策解读网站排名:五大权威平台全解析
童年缺爱的人,一生都在戒这几种瘾
电动景区观光车游览使用规定与手续
简单探讨10G-SR光模块中的COB工艺
从“吃饱”到“吃好” 中央一号文件强调“确保粮食稳产丰产”
姜盖膜种植技术图解:从传统地膜到新型PP发泡样本壳的应用
桂林10大景点全攻略:漓江、象鼻山、阳朔等精华景点详解
青岛本科大学大盘点:8所高校特色全解析
古老的泗河
银行预留印鉴需要哪些章?一文详解企业开户必备印章
存储可靠性:从基于磁盘的RAID到分布式纠删码(EC),多副本
获评国家3A级旅游景区,兴隆湖!
孕妈担心的CT辐射,一次性说清楚
巨轮智能(002031.SZ)2024年三季度经营业绩分析报告
泉州文旅热,一场政府、年轻人与本地文化的“共生实验”
桥梁自动监测系统设计方案:智能化监测助力桥梁安全
证券从业资格考试分为哪三个类别?附三者的区别
关心抑郁症朋友的话怎么说
政协首场大会点题生物医药,广州如何占据全球高地?丨广州向上2025
颛顼、帝喾、尧、舜、禹和黄帝的世系关系是怎么排列的
人口模型-马尔萨斯模型1
股骨颈骨折伤残等级划分标准探讨
什么是DCS?
深圳市妇联连续两年推出“父出行动”,解锁第“父+1”种可能
什么是斩获诺奖的量子玻尔兹曼机
监理日志常见问题、编写要点及填写模板
印度为何难以跨越成为发达国家的门槛?
颠覆认知!最新研究:多吃碳水反而更容易减肥,你吃够了吗?
是赠与还是彩礼?婚约财产不能一概而论
胃癌肝转移诊断与综合治疗中国专家共识(2024版)