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

news2024/11/25 2:41:31

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

单例模式的原理

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

  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.coloradmin.cn/o/2247030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

社交电商专业赋能高校教育与产业协同发展:定制开发AI智能名片及2+1链动商城小程序的创新驱动

摘要&#xff1a;本文围绕社交电商有望成为高校常态专业这一趋势展开深入探讨&#xff0c;剖析国家政策认可下其学科发展前景&#xff0c;着重阐述在专业建设进程中面临的师资短缺及实践教学难题。通过引入定制开发AI智能名片与21链动商城小程序&#xff0c;探究如何借助这些新…

数据指标与标签在数据分析中的关系与应用

导读&#xff1a;分享数据指标体系的文章很多&#xff0c;但讲数据标签的文章很少。实际上&#xff0c;标签和指标一样&#xff0c;是数据分析的左膀右臂&#xff0c;两者同样重要。实际上&#xff0c;很多人分析不深入&#xff0c;就是因为缺少对标签的应用。今天系统的讲解下…

使用Electron将vue2项目打包为桌面exe安装包

目录 一、下载electron模板项目 【electron-quick-start】​ 二、打开项目&#xff0c;安装所有依赖 三、在打exe包的时候报错是因为没有&#xff0c;需要检查并安装之后重新打包&#xff1b; 四、经过这么疯狂的一波操作之后&#xff0c;就可以打包出你想要的exe安装包&am…

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

Linux之NFS共享文件操作

一、注意点 以下操作使用root用户 代理端需要访问服务端的2049、111端口二、nfs下载 # 服务端和代理端都要安装 yum –y install rpcbind yum –y install nfs-utils三、配置共享目录-【服务端】 *修改/etc/exports文件&#xff0c;追加以下内容 /home/app_adm/test ip1(in…

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云 C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用 发布于 2021-06-10 00:10:59 7.1K0 举报 文章被收录于专栏&#xff1a;c#学习笔记 一、介绍 DockPanelSuite是托管在…

杰发科技AC7840——EEP中RAM的配置

sample和手册中示例代码的sram区地址定义不一样 这个在RAM中使用没有限制&#xff0c;根据这个表格留下足够空间即可 比如需要4096字节的eep空间&#xff0c;可以把RAM的地址改成E000&#xff0c;即E000-EFFF&#xff0c;共4096bytes即可。

web-03

CSS回顾 选择器 标签选择器 标签{}ID选择器 标签中定义ID属性。 #ID值{}类选择器 标签中使用class属性 .类名{}关于DIV/span div任意的大小的长方形&#xff0c;大小css&#xff1a; width, height控制。—换行 span-- 一行内 CSS常用属性 width/height 宽度/高度 定义&…

CI配置项,IT服务的关键要素

随着现今数字经济的不断发展&#xff0c;逐渐成熟的IT 基础设施已不再是简单的竞争优势&#xff0c;而已成为企业生存和发展的基石。然而&#xff0c;仅仅拥有强大的基础设施是不够的。为了保障 IT 服务的平稳运行和持续交付&#xff0c;企业还需要重点关注 IT 服务的核心构建模…

ApiChain-编写迭代单测用例

项目地址&#xff1a;ApiChain 项目主页 写单测用例&#xff0c;就像画一幅有向不循环的图&#xff0c;图中的每个节点是这个单测用例的每一个步骤&#xff0c;连线代表着数据的流向&#xff0c;这幅图通常有一个或者多个起点&#xff0c;但通常只有一个终点。起点的数据来源于…

九、FOC原理详解

1、FOC简介 FOC&#xff08;field-oriented control&#xff09;为磁场定向控制&#xff0c;又称为矢量控制&#xff08;vectorcontrol&#xff09;&#xff0c;是目前无刷直流电机&#xff08;BLDC&#xff09;和永磁同步电机&#xff08;PMSM&#xff09;高效控制的最佳选择…

企业OA管理系统:Spring Boot技术实现与案例研究

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足&#xff0c;创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管理系统的系统分析部…

【tensorflow的安装步骤】

创建一个虚拟环境 conda create -n tensorflow python3.6激活虚拟环境 conda activate tensorflow使用镜像源下载 pip install tensorflow1.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/特别特别重要的点&#xff01;&#xff01;&#xff01; 别用WiFi或者校园网下…

网络安全-web架构-nginx配置

1. nginx访问&#xff1a; 访问的是index.html&#xff0c; 访问ip访问的资源就是在/usr/share/nginx/html中&#xff1b; 当nginx不认识&#xff0c;浏览器认识的话&#xff0c;浏览器会自动渲染。 当nginx认识&#xff0c;浏览器不认识的话&#xff0c;浏览器会把它加载成…

ES6 模块化语法

目录 ES6 模块化语法 分别暴露 统一暴露 ​编辑 默认暴露 ES6 模块化引入方式 ES6 模块化语法 模块功能主要由两个命令构成&#xff1a;export 和 import。 ⚫ export 命令用于规定模块的对外接口&#xff08;哪些数据需要暴露&#xff0c;就在数据前面加上关键字即可…

基于Java Springboot高校洗浴管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

stm32如何接收舵机的控制信号(而不是控制舵机)

看到很多如何stm32用pwm信号控制舵机的文章,老生常谈了 我来写一个stm32接收pwm信号的例子 ,这个pwm信号是用来控制舵机的 背景: 我需要接收航模接收机的,用来控制舵机的pwm信号, 得到这个信号后,做其他事情. 初版代码 pwm.h#ifndef _pwm_H #define _pwm_H#include "s…

Postman之pm.test断言操作

系列文章目录 1.Postman之安装及汉化基本使用介绍 2.Postman之变量操作 3.Postman之数据提取 4.Postman之pm.test断言操作 5.Postman之newman Postman之pm.test断言操作 1.断言方法2.连接符3.条件判断符 用于验证请求的响应数据是否符合预期 1.断言方法 pm.test()&#xff1a;…

MySQL面试题补

内连接和外连接的区别&#xff1a; ○1.功能和用法不同&#xff1a;内连接是连接两表都满足情况的数据&#xff1b;而外连接是以一边的表为主表&#xff0c;另一个表只显示匹配的行&#xff1b; ○2.用途&#xff1a;内连接一般是用于检索不同表需要根据共同的列值进行匹配的&a…

查看浏览器的请求头

爬虫时用到了请求头&#xff0c;虽然可以用网上公开的&#xff0c;但是还是想了解一下本机浏览器的。以 Edge 为例&#xff0c;其余浏览器通用。 打开浏览器任一网页&#xff0c;按F12打开DevTools&#xff1b;或鼠标右键&#xff0c;选择“检查”。首次打开界面应该显示在网页…