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

【设计模式】【创建型模式(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 {// 私有静态变量,初始值为 nullprivate 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 = Nonedef __new__(cls):if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls)return cls._instancedef do_something(self):print("Doing something...")# 测试
singleton1 = Singleton()
singleton2 = Singleton()print(singleton1 is singleton2)  # 输出 True,表明它们是同一个实例
singleton1.do_something()

Go 实现

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

package mainimport "fmt"type Singleton struct{}var instance *Singletonfunc 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 函数来提供全局访问点。

总结

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

相关文章:

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

单例模式是一种常用的创建型设计模式&#xff0c;其目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 单例模式的原理 单例模式的核心在于控制类的实例化过程&#xff0c;通常通过以下方式实现&#xff1a; 私有化构造函数&#xff0c;防止外部直接实例化。…...

form表单的使用

模板 <template><el-form :model"formData" ref"form1Ref" :rules"rules"><el-form-item label"手机号" prop"tel"><el-input v-model"formData.tel" /></el-form-item><el-f…...

PDF内容提取,MinerU使用

准备环境 # python 3.10 python3 -m pip install huggingface_hub python3 -m pip install modelscope python3 -m pip install -U magic-pdf[full] --extra-index-url https://wheels.myhloli.com下载需要的模型 import json import osimport requests from huggingface_hub…...

SpringCloud篇(服务网关 - GateWay)

目录 一、简介 二、为什么需要网关 二、gateway快速入门 1. 创建gateway服务&#xff0c;引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…...

自动化测试之unittest框架详解

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 unittest 1、什么是Unittest框架&#xff1f; python自带一种单元测试框架 2、为什么使用UnitTest框架&#xff1f; >批量执行用例 >提供丰富的断…...

Vue3 provide 和 inject的使用

在 Vue 中&#xff0c;provide 和 inject 是 Composition API 的一对功能&#xff0c;用于父子组件之间的依赖注入。它们的作用是让父组件可以向其所有子组件提供数据或方法&#xff0c;而不需要通过逐层传递 props。 1. provide provide 用于父组件中&#xff0c;提供数据或…...

掌握Git分布式版本控制工具:从基础到实践

一、引言 在软件开发过程中&#xff0c;版本控制是不可或缺的一环。Git作为一种分布式版本控制工具&#xff0c;以其高效、灵活的特点&#xff0c;受到了广大开发者的青睐。本文将详细介绍Git的基本概念、工作流程、常用命令&#xff0c;以及在IntelliJ IDEA中的操作方法。 二、…...

AndroidStudio与开发板调试时连接失败或APP闪退的解决方案,涉及SELINUX及获取Root权限

现象 用AndroidStudio打开工程代码,点击运行后,报错: 解决方案 具体原因是尝试运行 su(通常用于获取超级用户权限)时失败了,提示 “Permission denied” 通过 CONFIG_SECURITY_SELINUX 变量控制 SElinux 开启或关闭 在vim /rk3568_android_sdk/device/rockchip/rk…...

VMWARE虚拟交换机的负载平衡算法

一、基于源虚拟端口的路由 虚拟交换机可根据 vSphere 标准交换机或 vSphere Distributed Switch 上的虚拟机端口 ID 选择上行链路。 基于源虚拟端口的路由是 vSphere 标准交换机和 vSphere Distributed Switch 上的默认负载平衡方法。 ESXi主机上运行的每个虚拟机在虚拟交换…...

安卓InputDispatching Timeout ANR 流程

1 ANR的检测逻辑有两个参与者: 观测者A和被观测者B&#xff0c;当然&#xff0c;这两者是不在同一个线程中的。2 A在调用B中的逻辑时&#xff0c;同时在A中保存一个标记F&#xff0c;然后做个延时操作C&#xff0c;延时时间设为T&#xff0c;这一步称为: 埋雷 。3 B中的逻辑如果…...

【Nginx从入门到精通】03 、安装部署-让虚拟机可以联网

文章目录 总结一、配置联网【Minimal 精简版】1.1、查看网络配置1.2、配置ip地址 : 修改配置文件 <font colororange>ifcfg-ens33Stage 1&#xff1a;输入指令Stage 2&#xff1a;修改参数Stage 3&#xff1a;重启网络Stage 4&#xff1a;测试上网 二、配置联网【Everyth…...

java 增强型for循环 详解

Java 增强型 for 循环&#xff08;Enhanced for Loop&#xff09;详解 增强型 for 循环&#xff08;也称为 “for-each” 循环&#xff09;是 Java 从 JDK 5 开始引入的一种便捷循环语法&#xff0c;旨在简化对数组或集合类的迭代操作。 1. 基本语法 语法格式 for (类型 变量…...

浪潮云启操作系统(InLinux) bcache宕机问题分析

前言 本文以一次真实的内核宕机问题为切入点&#xff0c;结合实际操作案例&#xff0c;详细展示了如何利用工具 crash对内核转储&#xff08;kdump&#xff09;进行深入分析和调试的方法。通过对崩溃日志的解读、函数调用栈的梳理、关键地址的定位以及代码逻辑的排查&#xff…...

038集——quadtree(CAD—C#二次开发入门)

效果如下&#xff1a; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.T…...

备赛蓝桥杯--算法题目(1)

1. 链表求和 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode *head nullptr, *tail nullptr;int carry 0;while (l1 || l2) {int n1 l1 ? l1->val: 0;int n2 l2 ? l2->val:…...

机器学习100道经典面试题库(二)

机器学习100道经典面试题库&#xff08;31-60&#xff09; 在大规模的语料中&#xff0c;挖掘词的相关性是一个重要的问题。以下哪一个信息不能用于确定两个词的相关性。 A、互信息 B、最大熵 C、卡方检验 D、最大似然比 答案&#xff1a;B 解析&#xff1a;最大熵代表了…...

Unet++改进37:添加KACNConvNDLayer(2024最新改进方法)

本文内容:添加KACNConvNDLayer 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 1.步骤一 新建block/kacn_conv.py文件,添加如下代码: import torch import torch.nn as nn##源码地址:https://github.com/SynodicMonth/ChebyKAN class KACNConvNDLaye…...

基于 Levenberg - Marquardt 法的 BP 网络学习改进算法详解

基于 Levenberg - Marquardt 法的 BP 网络学习改进算法详解 一、引言 BP&#xff08;Back Propagation&#xff09;神经网络在众多领域有着广泛应用&#xff0c;但传统 BP 算法存在收敛速度慢、易陷入局部最优等问题。Levenberg - Marquardt&#xff08;LM&#xff09;算法作…...

MySQL 8.0与PostgreSQL 15.8的性能对比

根据搜索结果&#xff0c;以下是MySQL 8.0与PostgreSQL 15.8的性能对比&#xff1a; MySQL 8.0性能特点&#xff1a; MySQL在处理大量读操作时表现出色&#xff0c;其存储引擎InnoDB提供了行级锁定和高效的事务处理&#xff0c;适用于并发读取的场景。MySQL通过查询缓存来提高读…...

qt连接postgres数据库时 setConnectOptions函数用法

连接选项&#xff0c;而这些选项没有直接的方法对应&#xff0c;你可能需要采用以下策略之一&#xff1a; 由于Qt SQL API的限制&#xff0c;你可能需要采用一些变通方法或查阅相关文档和社区资源以获取最新的信息和最佳实践。如果你确实需要设置特定的连接选项&#xff0c;并且…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...