单例设计模式(2)
单例设计模式(2)
单例模式存在的问题
单例对 OOP 特性的支持不友好
- oop的特性:封装、继承、多态、抽象;
- 以Id生成器代码为例,如果未来某一天,我们希望针对不同的业务采用不同的 ID 生成算法。比如,订单 ID 和用户 ID 采用不同的 ID 生成器来生成。为了应对这个需求变化,我们需要修改所有用到 IdGenerator 类的地方,这样代码的改动就会比较大。
单例会隐藏类之间的依赖关系
- 通过构造函数、参数传递等方式声明的类之间的依赖关系,我们通过查看函数的定义,就能很容易识别出来。
- 但是,单例类不需要显示创建、不需要依赖参数传递,在函数中直接调用就可以了。如果代码比较复杂,这种调用关系就会非常隐蔽。在阅读代码的时候,我们就需要仔细查看每个函数的代码实现,才能知道这个类到底依赖了哪些单例类。
单例对代码的扩展性不友好
- 以数据库连接池为例,数据库连接池是单例的,但是,在一个系统中存在慢sql,这些 SQL 语句在执行的时候,长时间占用数据库连接资源,导致其他 SQL 请求无法响应。我们需要将数据库连接池隔离开,一个是正常的sql执行,一个是慢sql的执行器;
- 如果设计为单例的模式,印象了扩展性
单例对代码的可测试性不友好
- 首先,单例模式的硬编码式使用方式使得在编写单元测试时无法轻松地通过 mock 替换依赖的外部资源,比如数据库。、
- 其次,单例类持有的成员变量相当于全局变量,被所有代码共享,
如果这些成员变量是可变的,就可能导致不同测试用例之间相互影响的问题, - 需要特别注意。这种情况类似于全局变量的使用,容易造成测试结果不确定性和测试用例之间的耦合。
单例不支持有参数的构造函数
- 数据库连接池的情况下,需要设置数据库连接池的大小、最大的连接数、连接存活时间等
替代方案
- 引入外部的配置类(可以使用代码的形式、可以采用从配置文件中加载的方式),在单例类初始化时,对单例类的成员变量进行赋值
/*** 配置类,在单例类中使用依赖注入的方式或者其他方式引入*/
class Config {public static int parmaA;public static int parmaB;
}/*** 单例类*/
public class Singleton {private static Singleton instance = null;private final int paramA;private final int paramB;public Singleton() {this.paramA = Config.parmaA;this.paramB = Config.parmaA;}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
替代方案
- 为了保证全局唯一,除了使用单例,我们还可以用静态方法来实现。这也是项目开发中经常用到的一种实现思路
// 静态方法实现方式
public class IdGenerator {private static AtomicLong id = new AtomicLong(0);
public static long getId() {return id.incrementAndGet();}
}
// 使用举例long id = IdGenerator.getId();
- 使用过程中的方法
// 1. 老的使用方式public demofunction() {
//...long id = IdGenerator.getInstance().getId();
//...}// 2. 新的使用方式:依赖注入public demofunction(IdGenerator idGenerator) {long id = idGenerator.getId();}// 外部调用demofunction()的时候,传入idGeneratorIdGenerator idGenerator = IdGenerator.getInsance();demofunction(idGenerator);
但是这是解决了决单例隐藏类之间依赖关系,对于其他的问题还是无法解决
- 我们本质上是实现类的全局唯一性,除了单例模式,我们还可以通过工厂方法,IOC容器等方案来保证
相关文章:
单例设计模式(2)
单例设计模式(2) 单例模式存在的问题 单例对 OOP 特性的支持不友好 oop的特性:封装、继承、多态、抽象;以Id生成器代码为例,如果未来某一天,我们希望针对不同的业务采用不同的 ID 生成算法。比如&#x…...
boost::asio 启用 io_uring(Linux 5.10)队列支持
欲启用 boost::asio 对于 io_uring 的支持,这需要以下几个先决条件; 1、boost 1.78 及以上发行版本 Revision History - 1.78.0 (boost.org) 2、Linux kernel 5.10 及以上发行版本 3、在预定义头文件(stdafx.h)、或编译器预定义…...
Android 自定义坐标曲线图(二)
Android 自定义坐标曲线图_android 自定义曲线图-CSDN博客 继上一篇文章,点击折线图上的点,显示提示信息进行修改,之前通过回调,调用外部方法,使用popupwindow或dialog来显示,但是这种方法对于弹框显示的位…...
每日OJ题_子序列dp⑧_力扣446. 等差数列划分 II - 子序列
目录 力扣446. 等差数列划分 II - 子序列 解析代码 力扣446. 等差数列划分 II - 子序列 446. 等差数列划分 II - 子序列 难度 困难 给你一个整数数组 nums ,返回 nums 中所有 等差子序列 的数目。 如果一个序列中 至少有三个元素 ,并且任意两个相邻…...
GOPROXY 代理设置
通常报错: 1.http: server gave HTTP response to HTTPS client 2.timeout 解决指令:(会话临时性),长久的可以在配置文件中配置 go env -w GOPROXYhttps://goproxy.cn,direct 长久的,在~/.bashrc文件中添加: expo…...
Redis面经
Redis面经 Redis缓存穿透、缓存击穿和缓存雪崩及解决方案概述缓存穿透详解及解决方案缓存击穿详解及解决方案缓存雪崩详解及解决方案 Redis持久化机制什么是数据持久化?Redis数据持久化概述RDB持久化的优缺点AOF持久化混合持久化 Redis缓存穿透、缓存击穿和缓存雪崩…...
【c++】类和对象(六)深入了解隐式类型转换
🔥个人主页:Quitecoder 🔥专栏:c笔记仓 朋友们大家好,本篇文章我们来到初始化列表,隐式类型转换以及explicit的内容 目录 1.初始化列表1.1构造函数体赋值1.2初始化列表1.2.1隐式类型转换与复制初始化 1.3e…...
什么是nginx正向代理和反向代理?
什么是代理? 代理(Proxy), 简单理解就是自己做不了的事情或实现不了的功能,委托别人去做。 什么是正向代理? 在nginx中,正向代理指委托者是客户端,即被代理的对象是客户端 在这幅图中,由于左边内网中…...
【Go】面向萌新的Gin框架知识梳理学习笔记
目录 Gin框架简介 路由&路由组 1. 定义基本路由 2. 参数传递 3. 查询字符串参数 4. 路由组 5. 路由中间件 模板渲染 1. 加载模板 2. 定义模板 3. 渲染模板 4. 自定义模板函数 返回json 1. 导入 Gin 包 2. 创建 Gin 引擎 3. 定义路由和处理器函数 4. 运行服…...
baseDao增删改查.
这里写目录标题 1、baseDao增删改查介绍2、basDao类3、BasDao类的作用 1、baseDao增删改查介绍 (1)、增加Create)操作: 通过BaseDao的insert方法可以向数据库中插入一条新的记录。 该方法接受一个实体对象作参数,将该对象的属性映射到表的字…...
什么是面向对象【大白话Java面试题】
什么是面向对象 同样是解决一个问题,面向对象的角度是将问题抽象成对象的形式。通过分类的思维方式,将问题分成几个解决方案的对象。给每个对象赋值属性和方法,对每个对象的细节进行面向过程的思维,执行自己的方法来解决问题。 …...
PyTorch 教程-快速上手指南
文章目录 PyTorch Quickstart1.处理数据2.创建模型3.优化模型参数4.保存模型5.加载模型 PyTorch 基础入门1.Tensors1.1初始化张量1.2张量的属性1.3张量运算1.3.1张量的索引和切片1.3.2张量的连接1.3.3算术运算1.3.4单元素张量转变为Python数值 1.4Tensor与NumPy的桥接1.4.1Tens…...
【有芯职说】数字芯片BES工程师
一、 数字芯片BES工程师简介 今天来聊聊数字芯片BES工程师,其中BES是Back End Support的缩写,就是后端支持的意思。其实这个岗位是数字IC前端设计和数字IC后端设计之间的一座桥,完成从寄存器传输级设计到具体工艺的mapping和实现。这个岗位在…...
暴力破解pdf文档密码
首先安装pdfcrack工具包 apt install pdfcrack 默认密码字典存储在/usr/share/wordlists里,是gz文件,将它解压并copy到pdf目录 然后使用pdfcrack破解 密码在最后一行user-password的单引号里...
蓝桥杯刷题第四天
思路: 这道题很容易即可发现就是简单的暴力即可完成题目,我们只需满足所有数的和为偶数即可保证有满足条件的分法,同时也不需要存下每个输入的数据,只需要知道他是偶数还是奇数即可,因为我们只需要偶数个奇数搭配在一块…...
03-数据库的用户管理
一、创建新用户 mysql> create user xjzw10.0.0.% identified by 1; Query OK, 0 rows affected (0.01 sec) 二、查看当前数据库正在登录的用户 mysql> select user(); ---------------- | user() | ---------------- | rootlocalhost | ---------------- 1 row …...
每日一题 --- 三数之和[力扣][Go]
三数之和 题目:15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意&#x…...
vue render 函数详解 (配参数详解)
vue render 函数详解 (配参数详解) 在 Vue 3 中,render 函数被用来代替 Vue 2 中的模板语法。 它接收一个 h 函数(或者是 createElement 函数的别名),并且返回一个虚拟 DOM。 render 函数的语法结构如下: render(h) …...
ubuntu23.10配置RUST开发环境
系统版本: gcc版本 下载rustup安装脚本: curl --proto =https --tlsv1.2 https://sh.rustup.rs -sSf | sh下载完成后会自动执行 选择默认安装选项 添加cargo安装目录到环境变量 vim ~/.bashrc<...
Vue性能优化--gZip
一、gZip简单介绍 1.1 什么是gzip gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chro…...
Java 程序员第 2 阶段:精通 SpringBoot 整合大模型,快速搭建基础服务
前言上一阶段我们掌握了原生 API 调用,但在大规模生产环境中,使用专业的 Java 框架能大幅提升开发效率。SpringAI 和 LangChain4j 是 Java 生态中最主流的大模型集成框架。本篇文章将手把手带你精通 SpringBoot 整合大模型,快速搭建企业级 AI…...
【灶台导航】 RAG系统的容错设计:从向量搜索到关键词降级,一个都不能少
当三个外部依赖都可能随时挂掉时,如何保证用户永远有响应?问题:完美主义害死人 做RAG系统时,我们很容易陷入一种思维定势:向量检索要准、LLM要强、整个链路要丝滑。但现实是——任何一个外部服务挂了,用户就…...
Standard计划突然限速?揭秘MJ v6.1后台配额算法变更,3步绕过队列延迟,今日生效
更多请点击: https://intelliparadigm.com 第一章:Standard计划限速事件的全貌还原 2024年Q2,Standard计划在多个云原生生产环境中突发性触发API速率限制(Rate Limiting),导致下游服务批量超时与重试风暴。…...
AI Agent配置文件供应链安全:AgentLint静态分析工具实战指南
1. 项目概述与核心价值最近在折腾AI编程助手,比如Claude Code和Cursor,发现它们的配置文件(.claude/、CLAUDE.md、.cursorrules)功能强大得有点吓人。这些文件不仅能定义代码风格,还能配置“技能”(Skills&…...
Bose-Hubbard模型与量子Gibbs态模拟技术解析
1. Bose-Hubbard模型与量子模拟基础在量子多体物理研究中,Bose-Hubbard模型作为描述玻色子在周期性势场中行为的标准模型,已成为连接理论预测与实验验证的关键桥梁。这个看似简单的模型却能展现出丰富的物理现象,从超流态到Mott绝缘态的量子相…...
Agent Skill Exchange:标准化AI技能库,赋能智能编程助手
1. 项目概述:Agent Skill Exchange 是什么,以及它为何重要 如果你最近在折腾 Claude Code、Cursor 或者 Codex 这类 AI 编程助手,可能会发现一个痛点:虽然它们很强大,但要让它们真正理解并调用你项目里特定的工具链、…...
Degrees of Lewdity中文本地化技术解析:从安装到优化的实践指南
Degrees of Lewdity中文本地化技术解析:从安装到优化的实践指南 Degrees of Lewdity作为一款备受欢迎的游戏,其英文界面一直是中文用户体验的主要障碍。本文提供的Degrees of Lewdity中文本地化技术解析,将系统指导您完成游戏汉化的全过程&a…...
硬件工程师显示器选购指南:从垂直分辨率到IPS面板的实战经验
1. 从“够用”到“爽用”:一个硬件工程师的显示器升级心路作为一名整天和代码、电路图、数据手册打交道的硬件工程师,我的工作台就是我的战场。而这块战场上最核心的装备,除了键盘鼠标,就是那块每天要盯着看至少八小时的显示器。几…...
别再只用BigGantt了!这个免费JIRA甘特图插件Gantt Suite,配置简单速度快
轻量高效的JIRA甘特图解决方案:Gantt Suite全面评测与迁移指南 在项目管理领域,甘特图作为可视化排期的黄金标准已有百年历史。然而当这一经典工具遇上现代敏捷开发平台JIRA时,许多团队却陷入了两难境地——要么忍受BigGantt等老牌插件的臃肿…...
字节投2000亿、DeepSeek募500亿:国产AI算力军备竞赛进入“核弹级“对决
一、一条被低估的新闻2026年5月,当大多数人还在关注GPT-5.5的幻觉率降了多少个百分点时,中国AI产业发生了一件更具战略意义的大事——字节跳动宣布2026年AI基础设施资本支出超2000亿元,几乎同时,DeepSeek传出拟募资最高500亿元&am…...
