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

【设计模式】【创建型模式(Creational Patterns)】之单例模式

单例模式是一种常用的创建型设计模式,其目的是确保一个类只有一个实例,并提供一个全局访问点。

单例模式的原理

单例模式的核心在于控制类的实例化过程,通常通过以下方式实现:

  1. 私有化构造函数,防止外部直接实例化。
  2. 提供一个静态方法或属性,用于返回类的唯一实例。
  3. 使用懒汉式或饿汉式初始化策略来创建实例。

UML 类图

下面是单例模式的UML类图:

+-----------------+
| Singleton       |
+-----------------+
| -instance: Singleton |
+-----------------+
| +getInstance(): Singleton |
| +doSomething(): void    |
+-----------------+

在这个UML类图中:

  • Singleton 类有一个私有的静态变量 instance,用来存储唯一的实例。
  • getInstance() 方法是一个静态方法,用于获取 Singleton 类的唯一实例。
  • doSomething() 是一个普通的方法,用于演示单例对象的功能。

Java 代码示例

这里提供两种常见的单例模式实现方式:懒汉式和饿汉式。

饿汉式(线程安全,加载速度较慢)
public class Singleton {
    // 在静态初始化器中创建实例,保证线程安全
    private static final Singleton INSTANCE = new Singleton();

    // 私有构造函数,防止外部实例化
    private Singleton() {}

    // 公共静态方法,提供全局访问点
    public static Singleton getInstance() {
        return INSTANCE;
    }

    // 示例方法
    public void doSomething() {
        System.out.println("Doing something...");
    }
}
懒汉式(线程安全,延迟加载)
public class Singleton {
    // 私有静态变量,初始值为 null
    private static Singleton instance;

    // 私有构造函数,防止外部实例化
    private Singleton() {}

    // 公共静态方法,提供全局访问点
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 示例方法
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

懒汉式优化:双重检查锁定(Double-Checked Locking)

为了提高性能,可以使用双重检查锁定来减少同步锁的开销:

public class Singleton {
    // 使用 volatile 关键字确保多线程环境下的可见性
    private static volatile Singleton instance;

    // 私有构造函数,防止外部实例化
    private Singleton() {}

    // 公共静态方法,提供全局访问点
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    // 示例方法
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

C++ 实现

在 C++ 中,我们可以使用静态成员变量和静态成员函数来实现单例模式。

#include <iostream>

class Singleton {
private:
    // 私有构造函数,防止外部实例化
    Singleton() {}

    // 删除拷贝构造函数和赋值操作符,防止拷贝
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 静态成员变量,存储唯一的实例
    static Singleton* instance;

public:
    // 静态成员函数,提供全局访问点
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }

    // 示例方法
    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }
};

// 初始化静态成员变量
Singleton* Singleton::instance = nullptr;

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->doSomething();
    return 0;
}

Python 实现

在 Python 中,可以通过模块级别的全局变量来实现单例模式,也可以使用装饰器或者元类。

class Singleton:
    _instance = None

    def __new__(cls):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

    def do_something(self):
        print("Doing something...")

# 测试
singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2)  # 输出 True,表明它们是同一个实例
singleton1.do_something()

Go 实现

在 Go 中,可以使用包级变量来实现单例模式。

package main

import "fmt"

type Singleton struct{}

var instance *Singleton

func GetInstance() *Singleton {
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

func (s *Singleton) DoSomething() {
    fmt.Println("Doing something...")
}

func main() {
    singleton := GetInstance()
    singleton.DoSomething()
}

解释

  • C++:使用了静态成员变量和静态成员函数来确保单例的唯一性和全局可访问性。同时删除了拷贝构造函数和赋值操作符,防止拷贝。
  • Python:使用了类的 __new__ 方法来控制实例的创建,确保只有一个实例存在。
  • Go:使用了包级变量 instance 来存储唯一的实例,并通过 GetInstance 函数来提供全局访问点。

总结

这些实现都遵循了单例模式的基本原则:确保一个类只有一个实例,并提供一个全局访问点。每种语言的实现方式有所不同,但核心思想是一致的。


http://www.kler.cn/a/403336.html

相关文章:

  • 3-22 ElementPlus:表单
  • 揭秘AIGC下的数字时代:交互设计的隐秘力量与未来革命
  • 项目:华清速递
  • 前端—Cursor编辑器
  • 从技术到产品:第三方美颜API助力实时直播平台的开发详解
  • python3 Flask应用 使用 Flask-SQLAlchemy操作MySQL数据库
  • 实现两个表格的数据传递(类似于穿梭框)
  • 代码随想录---八股文训练营Day40(总结)
  • 【Unity/Animator动画系统】多层动画状态机实现角色的基本移动
  • 散户持股增厚工具:智能T0算法交易
  • ProtonBase × Data for AI Meetup·杭州站
  • 深度学习:神经网络中线性层的使用
  • 网络协议之邮件协议(SMTP、POP3与IMAP)
  • 路由基础(全)
  • WPF Prism框架
  • WebGL进阶(七)深度缓冲区
  • Vue 3 国际化 (i18n) 最佳实践指南
  • 基于Ruoyi的同一token跨系统访问,后端单点登录并且鉴权方案
  • 手机领夹麦克风哪个牌子好,哪种领夹麦性价比高,热门麦克风推荐
  • 基于大数据爬虫数据挖掘技术+Python的网络用户购物行为分析与可视化平台(源码+论文+PPT+部署文档教程等)
  • C语言和C++的不同
  • .net6.0(.net Core)读取 appsettings.json 配置文件
  • 在云服务器搭建 Docker
  • 音视频pts/dts
  • Python设计模式详解之5 —— 原型模式
  • 浪潮服务器硬件与配置监控指标解读