浅谈:单例模式的弊端与对策

单例的弊端

回顾以下单例模式的定义:保证一个类仅有一个实例,并提供一个该实例的全局访问点。

这里提到了「 **全局 」**两个字,可见单例本质就是一种全局资源。

那自然无法避免全局对象的各种弊端;

如:

  • 滥用问题,任何人都可以使用该资源
  • 生命周期问题,该对象从构造起贯穿整个应用程序种
  • 缺乏灵活性,全局资源的修改将涉及直接使用和间接使用的全部模块
  • 测试的困难,使用全局资源点不方便进行单元测试

单例的避免

其实解决的方法有不少,这里展示注入的方式对取消单例。

怎么注入呢?通常可以通过对象的构造函数,或者 set 方法将原先的单例对象注入到目标对象中。

单例的方式

复制代码
class MySql {
public:
    static MySql& instance() {
        static MySql s_instance;
        return s_instance;
    }

public:
    void foo() {}

private:
    MySql() = default;
    ~MySql() = default;

private:
    MySql(const MySql&) = delete;
    MySql& operator=(const MySql&) = delete;
};

// 依赖于单例
class Widget {
private:
    MySql* sql;

public:
    Widget() {
        sql = &MySql::instance();
    }

    void refresh() {
        sql->foo();
        // TODO
    }
};

int main() {
    Widget widget;
    widget.refresh();
    // TODO
}

注入的方式

复制代码
class MySql {
public:
    MySql() = default;
    ~MySql() = default;

public:
    void foo() {}
};

// 完全独立的模块
class Widget {
private:
    MySql* sql;

public:
    Widget(MySql* sql) : sql(sql) {
    }

    void refresh() {
        sql->foo();
        // TODO
    }
};

int main() {
    MySql sql;
 
    // 通过构造器进行注入
    Widget widget(&sql);
    widget.refresh();
    // TODO
}
相关推荐
geovindu2 天前
java: Singleton Pattern
java·开发语言·后端·单例模式·设计模式·创建型模式
重生之我是Java开发战士22 天前
【Java SE】多线程(三):单例模式,阻塞队列,线程池与定时器
java·javascript·单例模式
许彰午24 天前
34_Java设计模式之单例模式
java·单例模式·设计模式
罗超驿25 天前
10.Java单例模式全解析:饿汉式与懒汉式实现及线程安全深度剖析
安全·单例模式·javaee
布朗克1681 个月前
33 设计模式精讲
java·单例模式·设计模式
雨浓YN1 个月前
基于设计模式的Winform软件框架-01Xml\Log\Ini日志(单例模式+生产者消费者模式)
单例模式·设计模式
仙俊红1 个月前
Java 单例模式:类里面为什么可以有自己类型的字段?
java·开发语言·单例模式
swordbob1 个月前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
谁似人间西林客1 个月前
工业大数据实战:看中国智造如何用数据驱动效率革命
大数据·单例模式
张小姐的猫1 个月前
【Linux】多线程 —— 线程池 | 单例模式 | 常见锁
linux·运维·服务器·c++·单例模式·设计模式·策略模式