【Java】设计模式——单例、工厂、代理模式

【Java设计模式】——单例、工厂、代理模式(2026保姆级深度版) 🛠️

大家好!这是《探索JAVA之路》设计模式系列第一篇,专攻最常用、最重要的三个模式:单例(Singleton)工厂(Factory)代理(Proxy)

这三个模式几乎出现在所有Java项目中(Spring全家桶、MyBatis、日志框架、缓存、RPC……到处都是它们的影子)。学完这篇,你不仅能手写,还能一眼看出源码里的应用,面试/重构直接起飞!

1. 设计模式总览(快速定位)

三大模式定位

  • 单例:创建型 —— 确保全局只有一个实例(资源唯一)
  • 工厂:创建型 —— 封装对象创建过程(解耦)
  • 代理:结构型 —— 控制对真实对象的访问(增强、保护、远程)

2. 单例模式(Singleton)—— “我只存在一个”

定义:一个类只有一个实例,并提供全局访问点。

适用场景:配置管理器、线程池、数据库连接池、Spring Bean(默认单例)、日志器、缓存等。

单例模式5种实现方式对比表(2026推荐)

实现方式线程安全懒加载性能代码复杂度推荐指数备注
饿汉式(静态常量)×★☆☆☆☆9.5最推荐,简单可靠
饿汉式(静态代码块)×★☆☆☆☆9.0同上
懒汉式(synchronized)★★☆☆☆6.0性能差
双重校验锁(DCL)★★★☆☆8.5经典,但volatile必加
静态内部类(Bill Pugh)★★☆☆☆9.8最优雅
枚举(Enum)★☆☆☆☆10.02026终极推荐,防反射/序列化

代码实现(最推荐两种)

// 1. 饿汉式(最简单,推荐新手直接用)
public class SingletonEager {
    private static final SingletonEager INSTANCE = new SingletonEager();
    private SingletonEager() {}               // 私有构造器
    public static SingletonEager getInstance() {
        return INSTANCE;
    }
}

// 2. 枚举单例(2026最推荐,防反射、序列化、克隆)
public enum SingletonEnum {
    INSTANCE;                                 // 天然单例

    public void doSomething() {
        System.out.println("我是枚举单例");
    }
}
// 使用:SingletonEnum.INSTANCE.doSomething();

饿汉 vs 懒汉 vs 枚举UML思维导图

单例破坏与防御:反射、序列化、克隆 —— 枚举天然免疫!

3. 工厂模式(Factory)—— “我来帮你造对象”

核心:将对象的创建与使用分离,符合开闭原则

三种工厂对比表

类型复杂度适用场景优点缺点
简单工厂★☆☆☆☆简单对象创建代码最少不符合开闭原则
工厂方法★★☆☆☆需要扩展产品族符合开闭原则类太多
抽象工厂★★★☆☆产品族(多个相关产品)扩展产品族极强结构复杂

简单工厂代码(日常最常用):

// 产品接口
interface Car {
    void drive();
}

// 具体产品
class Tesla implements Car { public void drive() { System.out.println("特斯拉加速!"); } }
class BMW implements Car { public void drive() { System.out.println("宝马启动!"); } }

// 简单工厂
class SimpleCarFactory {
    public static Car createCar(String type) {
        if ("Tesla".equals(type)) return new Tesla();
        if ("BMW".equals(type)) return new BMW();
        throw new IllegalArgumentException("未知车型");
    }
}

// 使用
Car car = SimpleCarFactory.createCar("Tesla");
car.drive();

工厂方法 & 抽象工厂UML

实战:Spring的 BeanFactoryApplicationContext 就是顶级工厂!

4. 代理模式(Proxy)—— “我帮你挡一下”

定义:为其他对象提供一种代理,以控制对这个对象的访问。

类型:静态代理、动态代理(JDK、CGLIB)、Spring AOP代理。

适用场景:权限控制、日志记录、事务、缓存、远程代理(RMI)、延迟加载。

静态代理代码(最清晰):

// 主题接口
interface IUserService {
    void login(String username);
}

// 真实对象
class UserServiceImpl implements IUserService {
    public void login(String username) {
        System.out.println(username + " 登录成功");
    }
}

// 代理
class UserServiceProxy implements IUserService {
    private IUserService target;
    public UserServiceProxy(IUserService target) { this.target = target; }

    public void login(String username) {
        System.out.println("【日志】有人尝试登录:" + username);  // 前置增强
        target.login(username);
        System.out.println("【日志】登录完成");                 // 后置增强
    }
}

// 使用
IUserService service = new UserServiceProxy(new UserServiceImpl());
service.login("张三");

动态代理UML & 静态代理对比

JDK动态代理(必须实现接口) vs CGLIB(基于子类,Spring默认)。

5. 三模式对比总结(面试必备)

模式类型核心目的关键关键词Spring中体现
单例创建型唯一实例一个实例、全局访问@Bean 默认 singleton
工厂创建型封装创建逻辑解耦、开闭原则BeanFactory、FactoryBean
代理结构型控制访问、增强功能代理、AOPAOP、@Transactional

一句话记忆

  • 单例:我只有一个
  • 工厂:我帮你造
  • 代理:我帮你挡/增强

作业(立即动手)

  1. 用枚举实现一个线程安全的配置单例
  2. 用工厂方法模式实现“支付工厂”(微信、支付宝)
  3. 给UserService加一个动态代理,实现登录前后日志记录

想看完整可运行Demo仓库Spring中这三个模式的源码解析、还是结合策略/观察者模式的进阶版

直接评论回复 “1”“2”“3”,我下一篇文章立刻奉上完整代码 + GitHub链接!

把这篇收藏 + 转发给正在学设计模式的同学吧 —— 掌握这三个模式,你的Java代码层次直接提升一个档次!✨

(本文所有代码基于JDK 17+实测,图片来自经典技术博客与UML图,欢迎对比学习)

文章已创建 4992

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部