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; }
}
}
总结
单例模式是一种简单但强大的设计模式,适用于需要全局唯一实例的场景。通过本文的介绍,我们了解了单例模式的基本概念、实现方式、常见问题及解决方案。希望这些内容能帮助你在实际开发中更好地应用单例模式,提高代码的质量和可维护性。
热门推荐
3000字长文,解读民国时期军阀的形成、混战,及军阀间的恩怨情仇(上)
为什么越来越多的人,从电梯高层搬回低层居住?专家指出四个硬伤
低楼层是指哪几层?居住选择与舒适性解析
乙木八字命运如何算,乙木在八字里的运用与用神取用
华为如何召开战略务虚研讨会?
股票连续缩量下跌,这通常意味着什么?
报案之路:北京经济案件律师解析经济犯罪案件的报案流程
干部考察材料的主要内容有哪些?
精准定位,高效传动:光栅编码器技术解析
属鸡人的晚年运势
法律实践创新研究
探索护眼茶饮:多种茶叶配方助力视力保护与改善
手机、平板、手表“国补”开启,江苏市场反应如何?
胡椒粉是白胡椒还是黑胡椒?胡椒粉和花椒粉的区别
人民法院案例库使用指南:查询、筛选、推荐与反馈全攻略
打印机墨盒漏了的修复方法(解决打印机墨盒漏墨问题的有效措施)
泰迪犬毛色变化原因及护理全攻略
彩礼返还:过错原则的适用与法律规定
拉屎特别臭怎么办?医生的专业解答来了
“张勋复辟”失败以后,各参与者结局如何?
PUBG无法初始化STEAM的几个解决办法
探究历史谜团:侯君集谋反事件的多维视角
湿热和湿寒症状区别是什么
债券基金投资指南:如何选择适合自己的债券基金
太空生活限制多,航天员该如何保持心理健康?
面条里有硼砂,老百姓该如何辨别和避免?
硼砂对人体有什么危害
所罗门七十二柱魔神全名单(所罗门72魔神)
古印度的文明史,除了宗教种姓制,我们还可以用另一个视角看印度
鳄鱼能在海中生存,还能捕杀鲨鱼,是真的吗?