当前位置: 首页 > news >正文

23种设计模式之《单例模式(Singleton)》在c#中的应用及理解

程序设计中的主要设计模式通常分为三大类,共23种:

1. 创建型模式(Creational Patterns)

  • 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。

  • 工厂方法模式(Factory Method):定义创建对象的接口,由子类决定实例化哪个类。

  • 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。

  • 建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。

  • 原型模式(Prototype):通过复制现有对象来创建新对象。

2. 结构型模式(Structural Patterns)

  • 适配器模式(Adapter):将一个类的接口转换成客户希望的另一个接口。

  • 桥接模式(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。

  • 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。

  • 装饰器模式(Decorator):动态地给对象添加职责,相比生成子类更为灵活。

  • 外观模式(Facade):为子系统中的一组接口提供一个统一的接口。

  • 享元模式(Flyweight):通过共享技术有效地支持大量细粒度对象。

  • 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

3. 行为型模式(Behavioral Patterns)

  • 责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合。

  • 命令模式(Command):将请求封装为对象,使你可以用不同的请求对客户进行参数化。

  • 解释器模式(Interpreter):给定一个语言,定义其文法的一种表示,并定义一个解释器。

  • 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。

  • 中介者模式(Mediator):定义一个中介对象来封装一系列对象之间的交互。

  • 备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

  • 观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。

  • 状态模式(State):允许对象在其内部状态改变时改变其行为。

  • 策略模式(Strategy):定义一系列算法,将它们封装起来,并使它们可以互相替换。

  • 模板方法模式(Template Method):定义一个操作中的算法骨架,将一些步骤延迟到子类中。

  • 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

下面是一个使用C#实现的单例模式示例代码,并附有详细的文字说明。

4. 单例模式代码示例

csharp

using System;

public class Singleton
{
    // 1. 定义一个静态变量来保存类的唯一实例
    private static Singleton _instance;

    // 2. 私有构造函数,防止外部通过new创建实例
    private Singleton()
    {
        Console.WriteLine("Singleton instance created.");
    }

    // 3. 提供一个全局访问点来获取唯一实例
    public static Singleton GetInstance()
    {
        // 如果实例不存在,则创建一个新的实例
        if (_instance == null)
        {
            _instance = new Singleton();
        }
        return _instance;
    }

    // 4. 示例方法
    public void DoSomething()
    {
        Console.WriteLine("Doing something in Singleton instance.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 获取单例实例
        Singleton singleton1 = Singleton.GetInstance();
        Singleton singleton2 = Singleton.GetInstance();

        // 调用实例方法
        singleton1.DoSomething();
        singleton2.DoSomething();

        // 检查两个实例是否相同
        if (singleton1 == singleton2)
        {
            Console.WriteLine("singleton1 and singleton2 are the same instance.");
        }
        else
        {
            Console.WriteLine("singleton1 and singleton2 are different instances.");
        }
    }
}

5. 代码说明

  1. 静态变量 _instance

    • _instance 是一个静态变量,用于保存类的唯一实例。

    • 由于是静态的,它在整个应用程序生命周期中只会存在一个实例。

  2. 私有构造函数

    • 构造函数被声明为 private,防止外部代码通过 new 关键字直接创建实例。

    • 这是单例模式的核心,确保类的实例化只能由类自身控制。

  3. 全局访问点 GetInstance

    • GetInstance 是一个静态方法,用于提供对单例实例的全局访问。

    • 如果 _instance 为 null,则创建一个新的实例并赋值给 _instance;否则直接返回现有的实例。

    • 这种方法称为“懒汉式单例”,因为实例是在第一次访问时才创建的。

  4. 示例方法 DoSomething

    • 这是一个普通的方法,用于演示单例实例的功能。

    • 你可以通过单例实例调用这个方法。

  5. 主程序验证

    • 在 Main 方法中,通过 GetInstance 获取两个单例实例 singleton1 和 singleton2

    • 调用它们的 DoSomething 方法,并检查它们是否是同一个实例。

    • 如果输出显示 singleton1 和 singleton2 是同一个实例,则说明单例模式实现成功。


6. 输出结果

运行上述代码后,输出如下:

Singleton instance created.
Doing something in Singleton instance.
Doing something in Singleton instance.
singleton1 and singleton2 are the same instance.

7. 单例模式的特点

  1. 唯一性

    • 确保一个类只有一个实例。

  2. 全局访问点

    • 提供一个全局访问点,方便其他代码获取该实例。

  3. 延迟初始化

    • 实例在第一次被访问时才创建,节省资源。

  4. 线程安全问题

    • 上述代码在单线程环境下是安全的,但在多线程环境下可能会创建多个实例。

    • 可以通过加锁(lock)或使用静态构造函数来确保线程安全。


8. 线程安全的单例模式(改进版)

如果需要支持多线程环境,可以使用以下改进版代码:

csharp

using System;

public class Singleton
{
    private static readonly object _lock = new object();
    private static Singleton _instance;

    private Singleton()
    {
        Console.WriteLine("Singleton instance created.");
    }

    public static Singleton GetInstance()
    {
        if (_instance == null)
        {
            lock (_lock)
            {
                if (_instance == null)
                {
                    _instance = new Singleton();
                }
            }
        }
        return _instance;
    }

    public void DoSomething()
    {
        Console.WriteLine("Doing something in Singleton instance.");
    }
}
  • 使用 lock 关键字确保多线程环境下只有一个线程可以创建实例。

  • 双重检查锁定(Double-Check Locking)进一步优化性能,避免每次访问都加锁。

相关文章:

  • BUUCTF [CISCN 2019 初赛]Love Math
  • ONNX Runtime 与 CUDA、cuDNN 的版本对应
  • 【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter17-事件
  • 【大模型】DeepSeek 的人工智能发展之路
  • 【SpringBoot教程】Spring Boot + MySQL + Druid连接池整合教程
  • 懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)
  • 当Qt遇见IOCP:用C++打造高并发服务器
  • Android 动态加入Activity 时 manifest 注册报错解决。使用manifestPlaceholders 占位
  • QML 状态机 与 动画
  • fpga助教面试题
  • 【分布式理论15】分布式调度1:分布式资源调度的由来与过程
  • 深入解析SORT多目标跟踪算法:从原理到实现
  • 【虚拟仪器技术】第二章 虚拟仪器及其构成原理,体系结构,系统定义,系统集成
  • Unity3D 基于 GPU 动画和 Compute Shader 的大批量动画渲染详解
  • 【HappyBase】连接hbase报错:ecybin.ProtocolError: No protocol version header
  • 元数据服务器的概述
  • java后端开发day17--ArrayList--集合
  • jQuery AJAX 方法详解
  • CAN总线常见的错误帧及产生原因
  • 23种设计模式 - 桥接模式
  • 中国科学院院士、我国航天液体火箭技术专家朱森元逝世
  • 外交部:中方对美芬太尼反制仍然有效
  • 因操纵乙烯价格再遭诉讼,科莱恩等四家企业被陶氏索赔60亿
  • 夜读|尊重生命的棱角
  • 熊出没!我驻日本札幌总领馆提示中国公民注意人身安全
  • 甩掉“肥胖刺客”,科学减重指南来了