吃透 Java 常用设计模式:从原理到企业级实战(含 SpringBoot 应用 + 代码案例)
设计模式是前辈们总结的代码设计经验,是解决特定场景问题的 “最优解模板”。在 Java 开发中,无论是 JDK 源码、SpringBoot 框架,还是企业级业务系统,设计模式都无处不在。掌握设计模式,不仅能提升代码的可读性、可扩展性,更是从 “初级开发者” 迈向 “中级开发者” 的关键一步。
今天,我将聚焦 Java 中最常用的 8 种设计模式,结合 JDK 源码、SpringBoot 底层实现和企业级实战场景,用 “原理 + 场景 + 代码” 的方式深度拆解,让你看完就能用在项目中。
一、设计模式总览:为什么要学设计模式?
1. 设计模式的核心价值
- 解耦:分离业务逻辑与通用逻辑,降低代码耦合度;
- 复用:通用模板直接复用,减少重复编码;
- 扩展:符合开闭原则(对扩展开放,对修改关闭),应对需求变更更灵活;
- 规范:统一代码设计风格,提升团队协作效率。
2. 常用设计模式分类(聚焦高频)
| 类型 | 常用模式 | 核心作用 |
|---|---|---|
| 创建型 | 单例模式、工厂模式、建造者模式 | 控制对象创建过程,降低创建成本 |
| 结构型 | 代理模式、装饰器模式、适配器模式 | 优化类 / 对象的组合关系,提升灵活性 |
| 行为型 | 策略模式、观察者模式 | 优化对象间的交互逻辑,解耦行为依赖 |
这些模式是企业开发中 “出场率” 最高的,尤其是 SpringBoot 框架几乎无缝集成了所有模式,我们逐一拆解。
二、创建型模式:如何优雅地创建对象?
创建型模式的核心是 “控制对象创建”,避免硬编码 new 对象导致的耦合问题。
1. 单例模式:全局唯一实例
(1)核心原理
保证一个类在整个应用中只有一个实例,且提供全局访问点。
(2)应用场景
- 无状态工具类(如日志工具类、配置工具类);
- 资源密集型对象(如数据库连接池、线程池);
- SpringBoot 中的 Bean 默认是单例模式(scope="singleton")。
(3)实战代码(推荐:双重检查锁 DCL 模式,JDK1.8 + 安全)
/**
* 单例模式:双重检查锁(DCL),线程安全且高效
*/
public class Singleton {
// volatile关键字:禁止指令重排序,保证instance可见性
private static volatile Singleton instance;
// 私有构造器:禁止外部new对象
private Singleton() {}
// 全局访问点
public static Singleton getInstance() {
// 第一次检查:避免频繁加锁(性能优化)
if (instance == null) {
// 加锁:保证多线程安全
synchronized (Singleton.class) {
// 第二次检查:防止多个线程同时进入锁区后重复创建
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
(4)SpringBoot 中的应用
Spring 容器中的 Bean 默认是单例,底层通过DefaultSingletonBeanRegistry实现,核心逻辑类似 DCL:
// Spring源码核心逻辑(简化)
public class DefaultSingletonBeanRegistry {
// 存储单例Bean的缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
public Object getSingleton(String beanName) {
// 先查缓存
Object singletonObject = singletonObjects.get(beanName);
if (singletonObject == null) {
// 加锁创建Bean
synchronized (this.singletonObjects) {
singletonObject = singletonObjects.get(beanName);
if (singletonObject == null) {
// 创建Bean实例(后续逻辑)
singletonObject = createBean(beanName);
singletonObjects.put(beanName, singletonObject);
}
}
}
return singletonObject;
}
}
2. 工厂模式:封装对象创建逻辑
(1)核心原理
定义一个创建对象的接口,让子类决定创建哪个类的实例,工厂类负责统一管理创建逻辑。
(2)应用场景
- 对象创建逻辑复杂(如需要初始化配置、依赖其他对象);
- 需根据不同条件创建不同对象(如支付方式选择:微信支付、支付宝支付);
- SpringBoot 中的
BeanFactory、ApplicationContext都是工厂模式的实现。
(3)实战代码(工厂方法模式)
第一步:定义产品接口(支付方式)
// 支付接口(产品接口)
public interface Payment {
void pay(double amount);
}
第二步:实现具体产品(微信支付、支付宝支付)
// 微信支付(具体产品)
public class WechatPayment implements Payment {
@Override
public void pay(double amount) {
System.out.println("微信支付:" + amount + "元");
}
}
// 支付宝支付(具体产品)
public class AlipayPayment implements Payment {
@Override
public void pay(double amount) {
System.out.println("支付宝支付:" + amount + "元");
}
}
第三步:定义工厂接口 + 具体工厂
// 支付工厂接口
public interface PaymentFactory {
Payment createPayment();
}
// 微信支付工厂
public class WechatPaymentFactory implements PaymentFactory {
@Override
public Payment createPayment() {
// 可在此处添加微信支付的初始化逻辑(如配置appId、密钥)
return new WechatPayment();
}
}
// 支付宝支付工厂
public class AlipayPaymentFactory implements PaymentFactory {
@Override
public Payment createPayment() {
// 支付宝初始化逻辑
return new AlipayPayment();
}
}
第四步:使用工厂创建对象
public class PaymentTest {
public static void main(String[] args) {
// 选择微信支付
PaymentFactory factory = new WechatPaymentFactory();
Payment payment = factory.createPayment();
payment.pay(100); // 输出:微信支付:100.0元
// 切换支付宝支付(无需修改业务逻辑,符合开闭原则)
factory = new AlipayPaymentFactory();
payment = factory.createPayment();
payment.pay(200); // 输出:支付宝支付:200.0元
}
}
(4)SpringBoot 中的应用
ApplicationContext是 Spring 的核心工厂,负责创建和管理所有 Bean:
// SpringBoot中获取Bean(工厂模式的典型使用)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 创建Spring容器(工厂)
ApplicationContext context = SpringApplication.run(Application.class, args);
// 从工厂获取Bean(产品)
PaymentService paymentService = context.getBean(PaymentService.class);
paymentService.processPayment(100);
}
}
3. 建造者模式:复杂对象的分步构建
(1)核心原理
将复杂对象的构建过程与表示分离,通过分步构建 + 链式调用,创建多属性、多配置的对象。
(2)应用场景
- 对象属性多(如 10 + 个属性),且部分属性可选;
- 需保证对象创建后不可变(final 属性);
- 常见框架:Lombok 的
@Builder注解、MyBatis 的SqlSessionFactoryBuilder。
(3)实战代码(手动实现建造者模式)
/**
* 复杂对象:用户订单(含多个必填+可选属性)
*/
public class Order {
// 必填属性(final,不可变)
private final String orderId;
private final String userId;
private final double totalAmount;
// 可选属性
private final String couponCode;
private final String address;
private final boolean isExpress;
// 私有构造器:仅允许Builder调用
private Order(Builder builder) {
this.orderId = builder.orderId;
this.userId = builder.userId;
this.totalAmount = builder.totalAmount;
this.couponCode = builder.couponCode;
this.address = builder.address;
this.isExpress = builder.isExpress;
}
// 建造者类(静态内部类)
public static class Builder {
// 必填属性(必须在构造器中传入)
private final String orderId;
private final String userId;
private final double totalAmount;
// 可选属性(默认值)
private String couponCode = "";
private String address = "";
private boolean isExpress = false;
// 建造者构造器(传入必填属性)
public Builder(String orderId, String userId, double totalAmount) {
this.orderId = orderId;
this.userId = userId;
this.totalAmount = totalAmount;
}
// 可选属性链式设置
public Builder couponCode(String couponCode) {
this.couponCode = couponCode;
return this; // 返回this,支持链式调用
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder isExpress(boolean isExpress) {
this.isExpress = isExpress;
return this;
}
// 构建最终对象
public Order build() {
return new Order(this);
}
}
// getter方法(无setter,保证不可变)
public String getOrderId() { return orderId; }
// 其他getter...
}
(4)使用建造者创建对象
public class OrderTest {
public static void main(String[] args) {
// 链式构建订单(清晰易懂,必填+可选属性分离)
Order order = new Order.Builder("ORDER_001", "USER_100", 399.9)
.couponCode("COUPON_50")
.address("北京市海淀区")
.isExpress(true)
.build();
System.out.println("订单ID:" + order.getOrderId());
System.out.println("是否加急:" + order.isExpress());
}
}
(5)SpringBoot 中的应用
Lombok 的@Builder注解可直接生成建造者模式,简化代码:
import lombok.Builder;
import lombok.Data;
@Data // 生成getter、setter、toString等
@Builder // 生成建造者模式
public class Order {
// 必填属性
private final String orderId;
private final String userId;
private final double totalAmount;
// 可选属性
private String couponCode = "";
private String address = "";
private boolean isExpress = false;
}
// 使用Lombok生成的建造者
Order order = Order.builder()
.orderId("ORDER_002")
.userId("USER_200")
.totalAmount(599.9)
.couponCode("COUPON_100")
.build();
三、结构型模式:如何优化类与对象的组合?
结构型模式的核心是 “优化类 / 对象的组合关系”,在不改变原有代码的前提下,提升系统的灵活性和复用性。
1. 代理模式:给对象找个 “中间人”
(1)核心原理
在不修改目标对象的前提下,通过代理对象控制对目标对象的访问,实现额外功能(如日志、权限、缓存)。
(2)应用场景
- 日志记录、性能监控(如记录接口调用耗时);
- 权限校验(如接口访问前验证登录状态);
- SpringAOP 的底层实现(JDK 动态代理 + CGlib 代理)。
(3)实战代码(JDK 动态代理,SpringAOP 底层)
第一步:定义目标接口(用户服务)
public interface UserService {
void queryUser(String userId);
}
第二步:实现目标对象(真实用户服务)
public class UserServiceImpl implements UserService {
@Override
public void queryUser(String userId) {
System.out.println("查询用户信息:userId=" + userId);
}
}
第三步:实现代理处理器(增强逻辑)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date;
// 代理处理器:定义增强逻辑(日志+耗时统计)
public class LogInvocationHandler implements InvocationHandler {
// 目标对象
private final Object target;
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强:记录日志和开始时间
System.out.println("【日志】" + new Date() + " 调用方法:" + method.getName());
long start = System.currentTimeMillis();
// 调用目标对象的核心方法
Object result = method.invoke(target, args);
// 后置增强:记录耗时
long end = System.currentTimeMillis();
System.out.println("【日志】方法执行耗时:" + (end - start) + "ms");
return result;
}
}
第四步:生成代理对象并使用
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
// 1. 创建目标对象
UserService userService = new UserServiceImpl();
// 2. 生成动态代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new LogInvocationHandler(userService)
);
// 3. 通过代理对象调用方法(自动增强)
proxy.queryUser("USER_100");
}
}
(4)运行结果
【日志】Thu Oct 12 15:30:00 CST 2023 调用方法:queryUser
查询用户信息:userId=USER_100
【日志】方法执行耗时:2ms
(5)SpringBoot 中的应用(AOP)
SpringAOP 通过代理模式实现切面增强,无需手动写代理类:
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect // 标记为切面
@Component
public class LogAspect {
// 切点:匹配UserService的所有方法
@Before("execution(* com.example.service.UserService.*(..))")
public void before() {
System.out.println("【AOP前置】记录接口调用日志");
}
@After("execution(* com.example.service.UserService.*(..))")
public void after() {
System.out.println("【AOP后置】记录接口执行结果");
}
}
2. 装饰器模式:动态给对象添加功能
(1)核心原理
动态地给一个对象添加额外功能,且不改变其原有结构(比继承更灵活)。
(2)应用场景
- 给核心功能添加可选增强功能(如 IO 流的缓冲、加密;接口的缓存、降级);
- 功能组合多样,避免继承导致的类爆炸;
- JDK 中的
BufferedReader、InputStream系列都是装饰器模式。
(3)实战代码(接口缓存装饰器)
第一步:定义核心接口(商品服务)
public interface ProductService {
String getProductInfo(String productId);
}
第二步:实现核心功能(真实商品服务)
public class ProductServiceImpl implements ProductService {
@Override
public String getProductInfo(String productId) {
// 模拟数据库查询(耗时操作)
System.out.println("【数据库查询】获取商品信息:productId=" + productId);
return "商品" + productId + ":手机,价格3999元";
}
}
第三步:实现装饰器(缓存增强)
import java.util.HashMap;
import java.util.Map;
// 装饰器:实现核心接口,持有目标对象引用
public class CacheProductDecorator implements ProductService {
// 持有目标对象
private final ProductService target;
// 缓存容器
private final Map<String, String> cache = new HashMap<>();
// 缓存过期时间(30秒)
private static final long CACHE_EXPIRE = 30 * 1000;
public CacheProductDecorator(ProductService target) {
this.target = target;
}
@Override
public String getProductInfo(String productId) {
// 1. 先查缓存
if (cache.containsKey(productId)) {
System.out.println("【缓存命中】获取商品信息:productId=" + productId);
return cache.get(productId);
}
// 2. 缓存未命中,调用目标对象查询
String productInfo = target.getProductInfo(productId);
// 3. 存入缓存(模拟过期时间,实际可用Redis)
cache.put(productId, productInfo);
return productInfo;
}
}
第四步:使用装饰器
public class DecoratorTest {
public static void main(String[] args) {
// 1. 创建核心对象
ProductService productService = new ProductServiceImpl();
// 2. 用装饰器包装核心对象(添加缓存功能)
ProductService cacheService = new CacheProductDecorator(productService);
// 第一次调用:缓存未命中,走数据库
System.out.println(cacheService.getProductInfo("PROD_001"));
// 第二次调用:缓存命中,直接返回
System.out.println(cacheService.getProductInfo("PROD_001"));
}
}
(4)运行结果
【数据库查询】获取商品信息:productId=PROD_001
商品PROD_001:手机,价格3999元
【缓存命中】获取商品信息:productId=PROD_001
商品PROD_001:手机,价格3999元
(5)JDK 中的应用
BufferedReader装饰FileReader,添加缓冲功能:
// JDK装饰器模式示例
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line = reader.readLine(); // 缓冲读取,提升效率
} catch (Exception e) {
e.printStackTrace();
}
3. 适配器模式:让不兼容的接口 “牵手”
(1)核心原理
将一个类的接口转换成客户端期望的另一个接口,解决接口不兼容的问题(如旧系统接口适配新系统)。
(2)应用场景
- 新旧系统集成(旧接口与新接口不兼容);
- 第三方组件适配(如支付接口、短信接口适配);
- SpringBoot 中的
HandlerAdapter(适配不同的 Controller 方法)。
(3)实战代码(支付接口适配)
第一步:新系统接口(目标接口)
// 新系统统一支付接口
public interface NewPaymentService {
// 新接口方法:支持订单号+金额+支付方式
void pay(String orderNo, double amount, String payType);
}
第二步:旧系统接口(待适配接口)
// 旧系统微信支付接口(接口不兼容)
public class OldWechatPayment {
// 旧接口方法:仅支持订单号+金额
public void wechatPay(String orderId, double money) {
System.out.println("旧系统微信支付:订单号=" + orderId + ",金额=" + money);
}
}
第三步:实现适配器
// 适配器:实现新接口,持有旧接口对象
public class WechatPaymentAdapter implements NewPaymentService {
// 持有旧接口对象
private final OldWechatPayment oldWechatPayment;
public WechatPaymentAdapter(OldWechatPayment oldWechatPayment) {
this.oldWechatPayment = oldWechatPayment;
}
@Override
public void pay(String orderNo, double amount, String payType) {
// 适配逻辑:将新接口参数转换为旧接口参数
if ("WECHAT".equals(payType)) {
oldWechatPayment.wechatPay(orderNo, amount);
}
}
}
第四步:使用适配器
public class AdapterTest {
public static void main(String[] args) {
// 1. 旧系统对象
OldWechatPayment oldPayment = new OldWechatPayment();
// 2. 适配器包装旧对象
NewPaymentService newPayment = new WechatPaymentAdapter(oldPayment);
// 3. 新系统调用统一接口(适配旧系统)
newPayment.pay("ORDER_003", 299.9, "WECHAT");
}
}
(4)SpringBoot 中的应用
HandlerAdapter适配不同的 Controller 方法(如 @RequestMapping、@GetMapping):
// SpringBoot源码核心逻辑(简化)
public interface HandlerAdapter {
boolean supports(Object handler); // 判断是否支持该Controller
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
// 适配@RequestMapping注解的Controller
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HandlerMethod && ((HandlerMethod) handler).hasRequestMapping();
}
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 适配逻辑:将HTTP请求转换为Controller方法参数
return handleInternal(request, response, (HandlerMethod) handler);
}
}
四、行为型模式:如何优化对象间的交互?
行为型模式的核心是 “优化对象间的通信”,解耦行为的发起者和接收者。
1. 策略模式:封装多变的算法
(1)核心原理
定义一系列算法,将每个算法封装成独立的类,让它们可以互相替换,且算法的变化不影响使用算法的客户端。
(2)应用场景
- 业务规则多变(如折扣计算、排序算法、校验规则);
- 多种支付方式、多种登录方式(如手机号登录、微信登录、QQ 登录);
- SpringBoot 中的
Resource(不同资源加载策略:文件、URL、ClassPath)。
(3)实战代码(折扣计算策略)
第一步:定义策略接口(折扣算法)
public interface DiscountStrategy {
// 计算折扣后价格
double calculateDiscount(double originalPrice);
}
第二步:实现具体策略
// 无折扣策略
public class NoDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double originalPrice) {
return originalPrice;
}
}
// 满减策略(满300减50)
public class FullReduceDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double originalPrice) {
if (originalPrice >= 300) {
return originalPrice - 50;
}
return originalPrice;
}
}
// 打折策略(9折)
public class RateDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double originalPrice) {
return originalPrice * 0.9;
}
}
第三步:定义上下文(使用策略的客户端)
public class OrderContext {
// 持有策略对象
private DiscountStrategy discountStrategy;
// 构造器注入策略
public OrderContext(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
// 切换策略
public void setDiscountStrategy(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
// 计算最终价格
public double calculateFinalPrice(double originalPrice) {
return discountStrategy.calculateDiscount(originalPrice);
}
}
第四步:使用策略模式
public class StrategyTest {
public static void main(String[] args) {
double originalPrice = 399.9;
// 1. 无折扣
OrderContext order = new OrderContext(new NoDiscountStrategy());
System.out.println("无折扣价格:" + order.calculateFinalPrice(originalPrice));
// 2. 切换满减策略
order.setDiscountStrategy(new FullReduceDiscountStrategy());
System.out.println("满减后价格:" + order.calculateFinalPrice(originalPrice));
// 3. 切换打折策略
order.setDiscountStrategy(new RateDiscountStrategy());
System.out.println("9折后价格:" + order.calculateFinalPrice(originalPrice));
}
}
(4)运行结果
无折扣价格:399.9
满减后价格:349.9
9折后价格:359.91
2. 观察者模式:发布 - 订阅式通信
(1)核心原理
定义对象间的一对多依赖关系,当一个对象(被观察者)状态变化时,所有依赖它的对象(观察者)都会收到通知并自动更新。
(2)应用场景
- 事件通知(如订单支付成功后,通知库存、物流、积分系统);
- 消息订阅(如公众号推送、消息队列的发布 - 订阅模式);
- SpringBoot 中的
ApplicationEvent和ApplicationListener(事件驱动)。
(3)实战代码(订单支付通知)
第一步:定义事件(被观察者的状态)
// 订单支付事件(被观察者)
public class OrderPaidEvent {
private final String orderId;
private final double amount;
public OrderPaidEvent(String orderId, double amount) {
this.orderId = orderId;
this.amount = amount;
}
// getter方法
public String getOrderId() { return orderId; }
public double getAmount() { return amount; }
}
第二步:定义观察者接口
// 观察者接口
public interface OrderListener {
void onOrderPaid(OrderPaidEvent event);
}
第三步:实现具体观察者
// 库存观察者:支付成功后扣减库存
public class InventoryListener implements OrderListener {
@Override
public void onOrderPaid(OrderPaidEvent event) {
System.out.println("【库存系统】订单" + event.getOrderId() + "支付成功,扣减库存");
}
}
// 积分观察者:支付成功后增加积分
public class PointListener implements OrderListener {
@Override
public void onOrderPaid(OrderPaidEvent event) {
int points = (int) event.getAmount(); // 1元=1积分
System.out.println("【积分系统】订单" + event.getOrderId() + "支付成功,增加" + points + "积分");
}
}
// 物流观察者:支付成功后创建物流单
public class LogisticsListener implements OrderListener {
@Override
public void onOrderPaid(OrderPaidEvent event) {
System.out.println("【物流系统】订单" + event.getOrderId() + "支付成功,创建物流单");
}
}
第四步:定义事件发布者(管理观察者)
import java.util.ArrayList;
import java.util.List;
// 事件发布者(被观察者的管理类)
public class OrderEventPublisher {
// 存储所有观察者
private final List<OrderListener> listeners = new ArrayList<>();
// 注册观察者
public void registerListener(OrderListener listener) {
listeners.add(listener);
}
// 移除观察者
public void removeListener(OrderListener listener) {
listeners.remove(listener);
}
// 发布事件(通知所有观察者)
public void publishEvent(OrderPaidEvent event) {
for (OrderListener listener : listeners) {
listener.onOrderPaid(event);
}
}
}
第五步:使用观察者模式
public class ObserverTest {
public static void main(String[] args) {
// 1. 创建事件发布者
OrderEventPublisher publisher = new OrderEventPublisher();
// 2. 注册观察者
publisher.registerListener(new InventoryListener());
publisher.registerListener(new PointListener());
publisher.registerListener(new LogisticsListener());
// 3. 模拟订单支付成功,发布事件
OrderPaidEvent event = new OrderPaidEvent("ORDER_004", 299.9);
publisher.publishEvent(event);
}
}
(4)运行结果
【库存系统】订单ORDER_004支付成功,扣减库存
【积分系统】订单ORDER_004支付成功,增加299积分
【物流系统】订单ORDER_004支付成功,创建物流单
(5)SpringBoot 中的应用
SpringBoot 的事件驱动模型(基于观察者模式):
// 1. 定义事件(继承ApplicationEvent)
public class OrderPaidSpringEvent extends ApplicationEvent {
private final String orderId;
private final double amount;
public OrderPaidSpringEvent(Object source, String orderId, double amount) {
super(source);
this.orderId = orderId;
this.amount = amount;
}
// getter...
}
// 2. 定义观察者(实现ApplicationListener)
@Component
public class InventorySpringListener implements ApplicationListener<OrderPaidSpringEvent> {
@Override
public void onApplicationEvent(OrderPaidSpringEvent event) {
System.out.println("【Spring事件】库存系统:订单" + event.getOrderId() + "支付成功");
}
}
// 3. 发布事件(注入ApplicationEventPublisher)
@Service
public class OrderService {
private final ApplicationEventPublisher publisher;
// 构造器注入
public OrderService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void payOrder(String orderId, double amount) {
// 模拟支付逻辑
System.out.println("订单" + orderId + "支付成功");
// 发布事件
publisher.publishEvent(new OrderPaidSpringEvent(this, orderId, amount));
}
}
五、企业级开发设计模式选型指南
| 业务场景 | 推荐设计模式 | 举例说明 |
|---|---|---|
| 全局唯一对象(工具类、连接池) | 单例模式 | Spring Bean、Redis 连接池 |
| 多类型对象创建(支付、登录) | 工厂模式 | 多种支付方式创建、登录方式选择 |
| 复杂对象构建(多属性订单、配置) | 建造者模式 | 订单创建、配置类构建 |
| 日志、权限、监控(无侵入增强) | 代理模式 | Spring AOP、接口权限校验 |
| 功能动态增强(缓存、加密) | 装饰器模式 | IO 流缓冲、接口缓存 |
| 新旧系统集成、第三方接口适配 | 适配器模式 | 旧支付接口适配新系统 |
| 多变业务规则(折扣、排序) | 策略模式 | 多种折扣计算、排序算法选择 |
| 事件通知、发布订阅 | 观察者模式 | 订单支付后多系统通知 |
六、总结
设计模式不是 “银弹”,没有最好的模式,只有最适合的场景。学习设计模式的核心,不是死记硬背模板,而是理解其 “解耦、复用、扩展” 的设计思想。
在企业级开发中,我们不需要刻意追求 “用遍所有模式”,而是在遇到特定问题时,能想到对应的模式解决方案。比如:
- 想避免重复创建对象 → 用单例模式;
- 想给接口加日志但不想改原有代码 → 用代理模式;
- 想让不同系统解耦通信 → 用观察者模式。
同时,SpringBoot 等框架已经帮我们封装了大量设计模式,理解这些模式的底层实现,能让你更深入地掌握框架的使用技巧(如 AOP、事件驱动)。
希望这篇文章能带你从 “知道设计模式” 到 “会用设计模式”,在实际项目中写出更优雅、更易维护的代码!
更多推荐




所有评论(0)