设计模式-单例模式概述

我们常把23种经典的设计模式分为三类:创建型结构型行为型 ,其中创建型 设计模式主要解决"对象的创建"问题,将创建和使用代码解耦,结构型 设计模式主要解决"类或对象的组合或组装"问题,将不同功能代码解耦,行为型设计模式主要解决"类或对象之间的交互"问题,将不同的行为代码解耦。

原理

是一种创建型模式,一个类只允许创建一个实例对象,那这个类就是个单例类。

实现

①构造函数私有化,避免外部通过new创建实例;

②考虑对象创建时的线程安全问题;

③考虑是否支持延迟加载;

④考虑getInstance()性能是否高(是否加锁)

⑤考虑序列化和反序列化是否会破坏单例

⑥考虑反射攻击单例

饿汉式

饿汉式的实现方式,在类加载期间,就已经将instance静态实例初始化好了,所以instance实例的创建是线程安全 的。不过这样的实现不支持延迟加载 实例。 | 懒汉式相对于饿汉式的优势是支持延迟加载。这种实现方式会导致频繁加锁、释放锁,以及并发度低等问题,频繁的调用会产生性能瓶颈。

懒汉式

懒汉式相对于饿汉式的优势是支持延迟加载。这种实现方式会导致频繁加锁、释放锁,以及并发度低等问题,频繁的调用会产生性能瓶颈。

双重检测

双重检测实现方式既支持延迟加载、又支持高并发的单例实现方式。只要instance被创建之后,再调用getInstance()函数都不会进入到加锁逻辑中。所以这种方式解决了懒汉式并发度低的问题。(解决指令重排序,可以给instance成员变量加上volatile关键字)

静态内部类

利用 Java 的静态内部类来实现单例。这种实现方式,既支持延迟加载,也支持高并发,instance的唯一性,创建过程的线程安全性,都由JVM保证。实现起来比双重检测简单。

枚举

最简单的实现方式,基于枚举类型的单例实现。这种实现方式通过Java枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。还可解决序列化和反序列化生成新的实例。

应用场景

从业务概念上,有些数据在系统中应该保存一份,就比较适合设计为单例类。比如,系统的配置信息类,除此之外,还可以使用单例解决资源访问冲突的问题(分布式锁和并发队列亦可解决)。

存在问题

  • 单例对OOP特性支持不友好;
  • 单例会隐藏类之间的依赖关系;
  • 单例对代码扩展性不友好;
  • 单例对代码的可测试性不友好;
  • 单例不支持有参数的构造函数。

替代方案

静态方法(不推荐)、工厂模式、Spring IOC容器

作者:京东零售 马宏伟

来源:京东云开发者社区 转载请注明来源

相关推荐
Sam_Deep_Thinking19 小时前
结算分摊的策略模式:不同营销活动的扣点计算方案
java·设计模式·架构·系统架构
故渊at1 天前
系列一:架构思想进阶 | 第3篇 SOLID 原则与设计模式实战:从“代码搬运工”到“架构师”的必经之路
观察者模式·设计模式·重构·架构·代理模式
珊瑚里的鱼1 天前
手撕单例模式中的饿汉模式和懒汉模式,懒汉模式还要再多加一个C++11版本的
开发语言·c++·单例模式
老码观察2 天前
设计模式实战解读(十一):外观模式——给复杂系统套一层壳
python·设计模式·外观模式
AI大法师2 天前
奥迪 AUDI 案例:母品牌和新业务怎么拆?
大数据·设计模式·汽车
bryant_meng2 天前
【Design Patterns】23 Design Patterns: The Ultimate Developer‘s Toolkit
设计模式·编程·计算机科学·设计·工程
狂人开飞机2 天前
18. 中介者模式(Mediator Pattern)
设计模式·c#·中介者模式
韩曙亮2 天前
【Flutter】Dart 单例 ( 单例模式核心规则 | 饿汉式单例 | 懒汉式单例 | 极简空安全 懒汉式单例 | 工厂构造函数单例 )
flutter·单例模式·dart·饿汉式单例·懒汉式单例·空安全·空赋值
咖啡八杯2 天前
GoF设计模式——外观模式
java·设计模式·外观模式
江湖中的阿龙2 天前
23种设计模式
java·开发语言·设计模式