请评估我基于视频修改的Singleton单例模式实现是否正确?
单例模式实现规范验证
我参考视频实现了Singleton单例模式,对原有实现做了部分修改,想确认该实现是否符合单例模式的通用规范。我的单例类代码如下:
internal class CSingleton { // Aquí guardamos la única instancia que va a existir. private static object instance; // Creamos el constructor privado. private CSingleton() { } public static object ObtenInstancia() { if (instance == null) { instance = new COctopus(); } // Aseguramos que se crea una sola vez. return instance; } private class COctopus { private readonly string figure = "\t\t\t\t\t °°°°°°°°\r\n\t\t\t\t\t\t°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°° °°°°°°° °°°°°°° \r\n\t\t\t °\t °°°°°°°°°°°°°°°°°°°° \t \r\n\t\t\t °°\t ° °°°°°°°°°°°°°°°° ° \r\n\t\t\t °°°\t °°\t\t°°°°°°°°°°°°° °° °\r\n\t\t\t °°°\t °°° °°°°°°°°°° °°° °°\r\n\t\t\t °°°° \t °°°°°°°° °°°\r\n\t\t\t °°°°°\t °°°°°\t\t °°°\r\n\t\t\t °°°°°\t °°°°\r\n\t\t\t °°°°° °°°°\t -\t - °°°° °°°°°\r\n\t\t\t °°°\t °°° / \\ / \\ °°°\t °°°°\r\n\t\t\t\t\t °°°\t | \/ | °°° °°°\r\n\t\t\t\t\t °°\t \\ / °°\r\n\t\t\t\t\t °° \\ / °°\r\n\t\t\t\t\t ° \\ / °\r\n\t\t\t\t\t\t \\ /\t\r\n\t\t\t\t\t\t \_/\t"; public override string ToString() { return String.Format(figure); } } }
当前实现的问题分析
- 核心逻辑偏差:你声明的
CSingleton类并未作为单例实例被创建——私有构造函数从未被调用,实际返回的是内部COctopus的实例,且返回类型为object,外部使用时必须强制转换,违背了单例模式“对外暴露清晰类型实例”的设计初衷。 - 线程不安全:在多线程场景下,多个线程可能同时通过
if (instance == null)的判断,导致创建多个COctopus实例,破坏单例的唯一性。 - 职责混淆:
CSingleton仅作为实例容器,未承载实际业务逻辑,而COctopus才是实际的功能类,这种设计不符合单一职责原则,代码可读性差。
修正后的合规实现
如果你的目标是让COctopus成为单例,或者让单例类承载对应的功能,这里提供两种常见的合规实现:
方案1:双重检查锁定(线程安全的懒加载单例)
适合需要延迟加载、且需保证多线程安全的场景:
internal class OctopusSingleton { // 标记为volatile,避免指令重排序导致的空引用问题 private static volatile OctopusSingleton _instance; private static readonly object _lockObj = new object(); private readonly string _figure = "\t\t\t\t\t °°°°°°°°\r\n\t\t\t\t\t\t°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°° °°°°°°° °°°°°°° \r\n\t\t\t °\t °°°°°°°°°°°°°°°°°°°° \t \r\n\t\t\t °°\t ° °°°°°°°°°°°°°°°° ° \r\n\t\t\t °°°\t °°\t\t°°°°°°°°°°°°° °° °\r\n\t\t\t °°°\t °°° °°°°°°°°°° °°° °°\r\n\t\t\t °°°° \t °°°°°°°° °°°\r\n\t\t\t °°°°°\t °°°°°\t\t °°°\r\n\t\t\t °°°°°\t °°°°\r\n\t\t\t °°°°° °°°°\t -\t - °°°° °°°°°\r\n\t\t\t °°°\t °°° / \\ / \\ °°°\t °°°°\r\n\t\t\t\t\t °°°\t | \/ | °°° °°°\r\n\t\t\t\t\t °°\t \\ / °°\r\n\t\t\t\t\t °° \\ / °°\r\n\t\t\t\t\t ° \\ / °\r\n\t\t\t\t\t\t \\ /\t\r\n\t\t\t\t\t\t \_/\t"; // 私有构造函数,禁止外部实例化 private OctopusSingleton() { } public static OctopusSingleton GetInstance() { if (_instance == null) { lock (_lockObj) { // 二次检查,避免锁等待期间实例已被创建 if (_instance == null) { _instance = new OctopusSingleton(); } } } return _instance; } public override string ToString() { return _figure; } }
方案2:嵌套类实现延迟加载(线程安全,CLR自动保证)
利用CLR的类加载机制实现天然的线程安全和延迟加载,是推荐的简洁实现:
internal class OctopusSingleton { private readonly string _figure = "\t\t\t\t\t °°°°°°°°\r\n\t\t\t\t\t\t°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t\t\t °°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n °°°°°°°°°°°°°°°°°°°°°°°°°°°°\r\n\t\t\t \t °°°°°°° °°°°°°° °°°°°°° \r\n\t\t\t °\t °°°°°°°°°°°°°°°°°°°° \t \r\n\t\t\t °°\t ° °°°°°°°°°°°°°°°° ° \r\n\t\t\t °°°\t °°\t\t°°°°°°°°°°°°° °° °\r\n\t\t\t °°°\t °°° °°°°°°°°°° °°° °°\r\n\t\t\t °°°° \t °°°°°°°° °°°\r\n\t\t\t °°°°°\t °°°°°\t\t °°°\r\n\t\t\t °°°°°\t °°°°\r\n\t\t\t °°°°° °°°°\t -\t - °°°° °°°°°\r\n\t\t\t °°°\t °°° / \\ / \\ °°°\t °°°°\r\n\t\t\t\t\t °°°\t | \/ | °°° °°°\r\n\t\t\t\t\t °°\t \\ / °°\r\n\t\t\t\t\t °° \\ / °°\r\n\t\t\t\t\t ° \\ / °\r\n\t\t\t\t\t\t \\ /\t\r\n\t\t\t\t\t\t \_/\t"; private OctopusSingleton() { } // 嵌套类仅在GetInstance被调用时加载 private static class SingletonHolder { internal static readonly OctopusSingleton Instance = new OctopusSingleton(); } public static OctopusSingleton GetInstance() { return SingletonHolder.Instance; } public override string ToString() { return _figure; } }
内容的提问来源于stack exchange,提问作者Oscar RoAh
相关产品推荐
相关产品推荐

