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

cs 复制代码
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 是一个静态方法,用于提供对单例实例的全局访问。

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

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

  4. 示例方法 DoSomething

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

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

  5. 主程序验证

    • Main 方法中,通过 GetInstance 获取两个单例实例 singleton1singleton2

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

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


6. 输出结果

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

cs 复制代码
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

cs 复制代码
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)进一步优化性能,避免每次访问都加锁。

相关推荐
千千寰宇11 小时前
[设计模式/Java/多线程] 设计模式之单例模式【9】
设计模式·操作系统-进程/线程/并发
此木|西贝17 小时前
【设计模式】原型模式
java·设计模式·原型模式
“抚琴”的人18 小时前
【机械视觉】C#+VisionPro联合编程———【六、visionPro连接工业相机设备】
c#·工业相机·visionpro·机械视觉
rainFFrain18 小时前
单例模式与线程安全
linux·运维·服务器·vscode·单例模式
FAREWELL0007519 小时前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
CodeCraft Studio20 小时前
Excel处理控件Spire.XLS系列教程:C# 合并、或取消合并 Excel 单元格
前端·c#·excel
勘察加熊人21 小时前
forms实现连连看
c#
hvinsion21 小时前
PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具
c#·powerpoint·ppt·ppt助手·ppt翻页
weixin_307779131 天前
使用C#实现从Hive的CREATE TABLE语句中提取分区字段名和数据类型
开发语言·数据仓库·hive·c#
时光追逐者1 天前
在 Blazor 中使用 Chart.js 快速创建数据可视化图表
开发语言·javascript·信息可视化·c#·.net·blazor