从单例模式说起:Java 常见设计模式的理解与实践

文章目录

在 Java 后端开发中, 设计模式 几乎是绕不开的话题。
不论是日常业务开发、系统重构,还是技术面试,设计模式都会被反复提及。

但很多时候,我们停留在"知道名字、会背定义",却说不清楚:

  • 这个模式 为什么要用
  • 什么时候用才合适
  • 在真实项目中 到底解决了什么问题

一、什么是 Java 中的单例模式(Singleton)

1️⃣ 定义

单例模式是一种创建型设计模式,其核心目标是:

保证一个类在 JVM 中只有一个实例,并提供一个全局访问点。

通俗理解就是:

  • 这个类只能创建一个对象
  • 对象由自己控制创建
  • 外部通过统一入口访问

二、Java 中常见的单例实现方式

1、饿汉式(线程安全)

java 复制代码
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

优点

  • 实现简单
  • 天然线程安全

缺点

  • 类加载时就创建实例
  • 如果对象创建成本高,可能造成资源浪费

2、懒汉式(双重检查锁,推荐)

java 复制代码
public class Singleton {
    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;
    }
}

关键点说明:

  • volatile 防止指令重排
  • 双重 if 判断减少不必要的同步开销

这是企业级项目中非常常见的一种写法


3、静态内部类(最优雅)

java 复制代码
public class Singleton {
    private Singleton() {}

    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

特点:

  • 懒加载
  • 线程安全
  • 无需显式加锁,性能好

在很多场景下,这是综合性最优的单例实现方式


4、枚举单例(最安全)

java 复制代码
public enum Singleton {
    INSTANCE;
}

优点:

  • 天然防反射
  • 天然防反序列化
  • 《Effective Java》官方推荐

不足:

  • 不够灵活
  • 不适合复杂初始化逻辑

三、单例模式在真实项目中的使用场景

1️⃣ Spring 中的单例 Bean

java 复制代码
@Service
public class UserService {
}
  • Spring 默认 scope = singleton
  • 容器中只存在一个实例
  • 所有请求共享该对象

这其实是我们每天都在使用、却容易忽略的单例模式


2️⃣ 数据库连接池 / 线程池

java 复制代码
DataSource dataSource;
ExecutorService executorService;

使用单例的原因很明确:

  • 创建成本高
  • 需要全局共享
  • 需要统一管理资源

频繁创建只会带来性能和稳定性问题。


3️⃣ 工具类 / 管理类

java 复制代码
LogManager
ConfigManager
RedisClient

例如:

  • Redis 客户端管理
  • MinIO Client
  • MQ Producer / Consumer 管理器

这些类通常:

  • 不保存业务状态
  • 被多个模块复用
  • 非常适合单例模式

4️⃣ JVM 级别资源

java 复制代码
Runtime.getRuntime();

典型代表包括:

  • Runtime
  • System
  • Logger

这些都是 JVM 级别的全局唯一资源


四、单例模式的优缺点总结

✅ 优点

  • 减少对象创建,节省内存
  • 统一管理共享资源
  • 使用方便,全局可访问

❌ 缺点

  • 隐式依赖,不利于单元测试
  • 容易膨胀为"上帝类"
  • 多线程场景下实现复杂

单例模式不是银弹,关键在于是否用在合适的地方


五、除了单例,还有哪些常见设计模式?

创建型模式

模式 使用场景
Singleton 全局唯一实例
Factory 封装对象创建
Abstract Factory 创建产品族
Builder 构建复杂对象
Prototype 对象复制

结构型模式

模式 使用场景
Proxy AOP、权限、事务
Decorator 功能增强
Adapter 接口不兼容
Facade 对外统一入口
Composite 树形结构

行为型模式

模式 使用场景
Strategy 不同算法切换
Template Method 固定流程,步骤可变
Observer 事件通知
Chain of Responsibility 过滤器、拦截器
State 状态机、流程流转

六、总结

  • 单例模式是最常见、也最容易被滥用的设计模式
  • 真正重要的不是"会写代码",而是"知道什么时候该用"
  • 设计模式的本质是:让系统更容易维护和扩展
相关推荐
李少兄16 分钟前
Java 中只有值传递吗?
java·开发语言·python
名字还没想好☜28 分钟前
Spring @EventListener 事件驱动解耦实战:同步转异步、事务绑定与顺序控制
java·数据库·后端·python·spring
一木 之林36 分钟前
插件、MCP、Skill 的区别?
java·c++·人工智能
小刘在重生~43 分钟前
面试重点:final、finalize、finally 三者区别
java
边境悍匪1 小时前
蜗牛学苑 Java 智能体学习 Day39|SpringAI 会话存储、Function‑Call 工具调用、MCP 思维导图复盘
java·开发语言·spring boot·学习·阿里云
letisgo52 小时前
JAVA 高级进阶02篇《并发编程三板斧:JMM、CAS与AQS的源码级拆解》
java·面试·并发编程·aqs·jmm
胡写代码2 小时前
若依 + MyBatis-Plus,分页为什么悄悄失效了?
java·后端
yxlalm2 小时前
4.java秒杀项目第四课-后端商品后台接口
java·开发语言
宁之明起(B服)2 小时前
vulhub靶场(tomcat三件套:PUT写马、Ghostcat与manager弱口令)
java·tomcat
君顾12 小时前
家政派单小程序源码开发实战:从零搭建到上线全流程指南
java·开发语言·家政派单