从单例模式说起: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 状态机、流程流转

六、总结

  • 单例模式是最常见、也最容易被滥用的设计模式
  • 真正重要的不是"会写代码",而是"知道什么时候该用"
  • 设计模式的本质是:让系统更容易维护和扩展
相关推荐
a努力。2 小时前
中国电网Java面试被问:Dubbo的服务目录和路由链实现
java·开发语言·jvm·后端·面试·职场和发展·dubbo
爬山算法2 小时前
Hibernate(42)在Hibernate中如何实现分页?
java·后端·hibernate
不平衡的叉叉树2 小时前
我们遇到了正则表达式的灾难性回溯问题
java·正则表达式
Engineer邓祥浩2 小时前
设计模式学习(10) 23-8 装饰者模式
python·学习·设计模式
wangkay882 小时前
【Java 转运营】Day05:抖音新号起号:对标账号运营全指南
java·新媒体运营
大飞哥~BigFei2 小时前
新版chrome浏览器安全限制及解决办法
java·前端·chrome·安全·跨域
老蒋每日coding2 小时前
基于LangGraph的AI Agent并行化设计模式详解
设计模式·ai编程
GISer_Jing2 小时前
AI学习资源总结:免费开放,入门至深入,持续更新
人工智能·学习·设计模式·prompt·aigc