工作笔记 - 改进的单例应用

概述

单例是开发工作中常见的一种设计模式。

单例应用的基本概念是,在很多场景中,我们其实不需要创建很多对象,而是复用一个对象。比如像数据库连接这种情况,都是连接相同的数据库,如果一个操作,就要新建一个连接的话,系统资源可能很快就会用完。所以一个比较好的做法是,只创建一个数据库连接的实例,当要进行查询操作时,都只使用这个实例。

但在另外一些情况更复杂的情况中,这个单例可能就不太合适了。例如,要进行两个数据库的操作,虽然对于每个数据库都是单例,但在应用层面,可能需要同时的两个实例。传统的做法,可能需要再新建一个单例的类,这样可能会增加一些开发和维护的重复工作。

为此,笔者想到,可以将现在的单例模式扩展一下,让它能支持更复杂的应用场景。

传统实现

为了方便讨论,笔者在本文中是以熟悉的JS语言作为示例的,但实际上这个模式应当和具体实现语言无关。

传统的单例的实现,在JS语言中,大体如下:

some.js 复制代码
class Business ...

class Singleton  {
    private static instances: Bussiness = null;
        
    private constructor() {}; // 防止直接实例化

    static getInstance(config) {
        if (!Singleton.instances || config) 
            Singleton.instances = new Business(config);
            
        return Singleton.instances;
    }    
}

module.exports = Singleton;

// 初始化,系统启动
require("some").getInstance(config);

// 使用单例, 实际业务代码中
const some = require("some").getInstance();

实际上,这已经是一个改进的模式了。原理也比较简单清楚,就是使用一个专门的单例类,来处理单例的问题。实际上,真正的业务实例,是由这个单例类的静态私有属性来保存的。在这种模式下,笔者建议的应用方式是:

  • 在系统启动初始化的时候,使用配置信息,创建业务实例和单例
  • 后续在程序中,直接使用默认单例,无需关心配置信息,因为已经实例化

改进实现

虽然在传统代码中,我们好像也可以通过切换配置信息,来创建不同配置方式的业务单例,但显然那样不是很方便,特别是需要同时交互式的操作不同单例的时候,这时候可以考虑将这个标准单例的实现扩展一下,参考代码如下:

js 复制代码
class Business ...

class Singleton  {
    private static instances = [];
        
    private constructor() {}; // 防止直接实例化

    static getInstance(config, iorder = 0) {
         // exist instance onfig should be object or string 
        if (config && typeof config === "number") return Singleton.instances[config];

        if (!Singleton.instances[iorder] || config) 
            Singleton.instances[iorder] = new Business(config);
        return Singleton.instances[iorder];
    }    
}

module.exports = Singleton;

// 多个单例初始化
require("some").getInstance(config);
require("some").getInstance(config1,1);

// 使用特定单例
const some1  = require("some").getInstance();
const some2  = require("some").getInstance(1);

// 直接设置和使用
const some2  = require("some").getInstance(config3,1);

这个调整的改进和特点如下:

  • 无需改变传统的使用方式,因为虽然可以有多个代理,但默认是编号为0的那个
  • 可以通过实例编号,扩展和使用更大的单例
  • 还是使用单例类,但用它来保存一个业务实例数组
  • 程序自动判断是引用实例还是配置参数,方便后续使用
  • 开发者需要注意单例实例的初始化和编号引用的问题

小结

本文探讨了对于单例模式的扩展和改进,可以支持多个"单例"的使用场景。并提出了改进的技术实现方案、示例代码和建议的应用方式。

相关推荐
福兮说3 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
凤城老人5 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)5 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan5 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_6 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
yivifu7 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
weixin_448290258 小时前
书庐开发实战教学
javascript·css·html
默_笙8 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript
一木 之林8 小时前
DeepSeek Agent 开发(一)
开发语言·前端·javascript
晚安code10 小时前
设计模式入门:吃透 SOLID 原则与迪米特法则,再学 5 个高频模式
后端·设计模式