📘 Java 后端开发者必学设计模式实战手册
—— 23种经典模式中,真正值得你掌握的15种(附中文注释完整示例)
作者:资深 Java 架构师 · 一线实战经验沉淀
适用对象:Java 后端开发工程师(Spring Boot / 微服务 / 分布式系统)
目标:
✅ 不学“全”而学“精”
✅ 不背“名称”而懂“场景”
✅ 不写“样板”而能“实战”
✅ 所有代码均可直接复制到项目中运行(JDK 8+)
✅ 一、学习原则:不是23种都要学,而是这15种必须精通!
| 类别 | 模式名称 | 是否必须掌握 | 推荐理由 |
|---|---|---|---|
| 创建型 | 单例模式 | ✅ 必须 | 线程安全的全局唯一实例(连接池、配置) |
| 工厂方法 | ✅ 必须 | Spring 中大量使用,解耦对象创建 | |
| 抽象工厂 | ✅ 必须 | 多套配置/数据库驱动切换场景 | |
| 建造者 | ✅ 必须 | 构建复杂对象(SQL、DTO、请求体) | |
| 原型模式 | ⚠️ 了解 | Java 中 clone() 用得少,了解即可 | |
| 结构型 | 适配器 | ✅ 必须 | 第三方接口兼容(微信/支付宝 SDK) |
| 装饰器 | ✅ 必须 | AOP、日志、缓存、加密等横切关注点 | |
| 代理 | ✅ 必须 | Spring AOP、远程调用、懒加载 | |
| 外观 | ✅ 必须 | 微服务调用封装、子系统简化 | |
| 桥接 | ⚠️ 了解 | 多维度扩展(如 JDBC + 驱动 + 池) | |
| 组合 | ⚠️ 了解 | 树形结构(菜单、组织架构) | |
| 享元 | ⚠️ 了解 | 字符串池、缓存小对象(面试常问) | |
| 行为型 | 策略模式 | ✅ 必须 | 支付、折扣、排序、规则引擎 |
| 模板方法 | ✅ 必须 | 订单流程、审核流程、公共逻辑 | |
| 观察者 | ✅ 必须 | 事件驱动、消息通知、异步解耦 | |
| 责任链 | ✅ 必须 | 过滤器、权限校验、风控链 | |
| 命令模式 | ✅ 必须 | 异步任务、操作回滚、MQ 消息 | |
| 状态模式 | ✅ 必须 | 订单状态、流程状态机 | |
| 中介者 | ⚠️ 了解 | 多对象通信复杂时(如聊天室) | |
| 备忘录 | ⚠️ 了解 | 撤销操作(如编辑器) | |
| 迭代器 | ⚠️ 了解 | Java 集合已内置,无需手动实现 | |
| 解释器 | ❌ 不学 | 仅用于 DSL 解析(如 SQL 引擎),后端极少用 | |
| 访问者 | ❌ 不学 | AST 解析、编译器场景,后端几乎不用 |
✅ 结论:你只需精通这 10~15 种即可应对 95% 的后端开发场景!
👉 优先掌握:单例、工厂、策略、模板、观察者、责任链、命令、状态、装饰器、代理、外观
✅ 二、15种核心设计模式详解(含中文注释完整代码)
🔹 1. 单例模式(Singleton)—— 全局唯一实例
适用场景:数据库连接池、Redis 客户端、配置管理器、日志记录器
/**
* 饿汉式单例(线程安全,类加载时初始化)
* 优点:简单、线程安全、无锁
* 缺点:可能浪费内存(即使没用到也创建)
*/
public class DatabaseConnectionPool {
// 私有静态实例,类加载时创建
private static final DatabaseConnectionPool INSTANCE = new DatabaseConnectionPool();
// 私有构造函数,防止外部 new
private DatabaseConnectionPool() {
System.out.println("✅ 数据库连接池已初始化");
}
// 公共静态方法,提供全局访问点
public static DatabaseConnectionPool getInstance() {
return INSTANCE;
}
// 模拟获取连接
public void getConnection() {
System.out.println("🔗 获取数据库连接...");
}
}
// 使用示例
public class SingletonDemo {
public static void main(String[] args) {
DatabaseConnectionPool pool1 = DatabaseConnectionPool.getInstance();
DatabaseConnectionPool pool2 = DatabaseConnectionPool.getInstance();
System.out.println(pool1 == pool2); // true,证明是同一实例
pool1.getConnection(); // 输出:🔗 获取数据库连接...
}
}
✅ 推荐使用:饿汉式(简单安全)
❌ 避免使用:双重检查锁(Java 5 之前有缺陷,现在用volatile仍易出错)
💡 Spring 中替代:@Component默认就是单例
🔹 2. 工厂方法模式(Factory Method)—— 创建对象的接口
适用场景:不同支付方式、不同日志输出、不同数据库驱动
/**
* 支付方式接口(抽象产品)
*/
interface Payment {
boolean pay(double amount);
}
/**
* 微信支付实现类(具体产品)
*/
class WeChatPay implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("📱 微信支付 " + amount + " 元成功");
return true;
}
}
/**
* 支付宝支付实现类(具体产品)
*/
class Alipay implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("💳 支付宝支付 " + amount + " 元成功");
return true;
}
}
/**
* 工厂接口(创建者)
*/
interface PaymentFactory {
Payment createPayment();
}
/**
* 微信支付工厂(具体创建者)
*/
class WeChatPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new WeChatPay();
}
}
/**
* 支付宝支付工厂(具体创建者)
*/
class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
}
// 使用示例:客户端只依赖工厂接口
public class FactoryDemo {
public static void main(String[] args) {
// 根据配置动态选择工厂
PaymentFactory factory = getPaymentFactory("alipay");
// 创建支付对象,无需知道具体类型
Payment payment = factory.createPayment();
payment.pay(99.9); // 输出:💳 支付宝支付 99.9 元成功
}
// 模拟从配置文件读取
private static PaymentFactory getPaymentFactory(String type) {
switch (type) {
case "wechat": return new WeChatPayFactory();
case "alipay": return new AlipayFactory();
default: throw new IllegalArgumentException("不支持的支付方式");
}
}
}
✅ Spring 中体现:
ApplicationContext.getBean("xxx")就是工厂方法
💡 进阶建议:用Map<String, Supplier<Payment>>+ Lambda 替代多个工厂类
🔹 3. 抽象工厂模式(Abstract Factory)—— 创建产品族
适用场景:多套 UI 主题、多数据库驱动 + 连接池组合
/**
* 数据库连接接口(产品族1)
*/
interface Connection {
void connect();
}
/**
* MySQL 连接实现
*/
class MySQLConnection implements Connection {
@Override
public void connect() {
System.out.println("🔌 连接到 MySQL 数据库");
}
}
/**
* PostgreSQL 连接实现
*/
class PostgreSQLConnection implements Connection {
@Override
public void connect() {
System.out.println("🔌 连接到 PostgreSQL 数据库");
}
}
/**
* 数据库事务管理接口(产品族2)
*/
interface Transaction {
void begin();
void commit();
}
/**
* MySQL 事务实现
*/
class MySQLTransaction implements Transaction {
@Override
public void begin() {
System.out.println("🔄 MySQL 开始事务");
}
@Override
public void commit() {
System.out.println("✅ MySQL 提交事务");
}
}
/**
* PostgreSQL 事务实现
*/
class PostgreSQLTransaction implements Transaction {
@Override
public void begin() {
System.out.println("🔄 PostgreSQL 开始事务");
}
@Override
public void commit() {
System.out.println("✅ PostgreSQL 提交事务");
}
}
/**
* 抽象工厂接口:创建一组相关对象
*/
interface DatabaseFactory {
Connection createConnection();
Transaction createTransaction();
}
/**
* MySQL 工厂:创建 MySQL 产品族
*/
class MySQLFactory implements DatabaseFactory {
@Override
public Connection createConnection() {
return new MySQLConnection();
}
@Override
public Transaction createTransaction() {
return new MySQLTransaction();
}
}
/**
* PostgreSQL 工厂:创建 PostgreSQL 产品族
*/
class PostgreSQLFactory implements DatabaseFactory {
@Override
public Connection createConnection() {
return new PostgreSQLConnection();
}
@Override
public Transaction createTransaction() {
return new PostgreSQLTransaction();
}
}
// 使用示例
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 根据配置决定使用哪种数据库
DatabaseFactory factory = getDatabaseFactory("mysql");
// 客户端无需关心具体实现,只使用接口
Connection conn = factory.createConnection();
Transaction tx = factory.createTransaction();
conn.connect(); // 🔌 连接到 MySQL 数据库
tx.begin(); // 🔄 MySQL 开始事务
tx.commit(); // ✅ MySQL 提交事务
}
private static DatabaseFactory getDatabaseFactory(String dbType) {
return switch (dbType) {
case "mysql" -> new MySQLFactory();
case "postgresql" -> new PostgreSQLFactory();
default -> throw new IllegalArgumentException("不支持的数据库");
};
}
}
✅ Spring 中体现:
DataSource+JdbcTemplate的组合就是抽象工厂
💡 实际应用:多租户系统中,不同租户使用不同数据库厂商
🔹 4. 建造者模式(Builder)—— 分步构建复杂对象
适用场景:构建 SQL、HTTP 请求、DTO、复杂配置对象
/**
* 订单信息对象(复杂对象)
*/
public class Order {
private String orderId; // 订单ID
private String customerId; // 客户ID
private String address; // 收货地址
private double totalAmount; // 总金额
private String paymentMethod; // 支付方式
private String note; // 备注
// 私有构造器,只能通过 Builder 创建
private Order(Builder builder) {
this.orderId = builder.orderId;
this.customerId = builder.customerId;
this.address = builder.address;
this.totalAmount = builder.totalAmount;
this.paymentMethod = builder.paymentMethod;
this.note = builder.note;
}
// 静态内部类:建造者
public static class Builder {
private String orderId;
private String customerId;
private String address;
private double totalAmount;
private String paymentMethod;
private String note;
public Builder orderId(String orderId) {
this.orderId = orderId;
return this; // 返回 this,支持链式调用
}
public Builder customerId(String customerId) {
this.customerId = customerId;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder totalAmount(double totalAmount) {
this.totalAmount = totalAmount;
return this;
}
public Builder paymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
return this;
}
public Builder note(String note) {
this.note = note;
return this;
}
// 构建最终对象
public Order build() {
if (orderId == null || customerId == null || address == null) {
throw new IllegalStateException("订单ID、客户ID、地址为必填项");
}
return new Order(this);
}
}
// getter 方法(可选)
@Override
public String toString() {
return "Order{" +
"orderId='" + orderId + '\'' +
", customerId='" + customerId + '\'' +
", address='" + address + '\'' +
", totalAmount=" + totalAmount +
", paymentMethod='" + paymentMethod + '\'' +
", note='" + note + '\'' +
'}';
}
}
// 使用示例:链式构建,清晰易读
public class BuilderDemo {
public static void main(String[] args) {
Order order = new Order.Builder()
.orderId("ORD20240501001")
.customerId("CUST10086")
.address("北京市朝阳区XX路1号")
.totalAmount(299.9)
.paymentMethod("支付宝")
.note("请尽快发货,谢谢!")
.build(); // 最后调用 build() 创建对象
System.out.println(order);
// 输出:
// Order{orderId='ORD20240501001', customerId='CUST10086', address='北京市朝阳区XX路1号', totalAmount=299.9, paymentMethod='支付宝', note='请尽快发货,谢谢!'}
}
}
✅ Java 标准库:
StringBuilder、StringJoiner、java.time.LocalDateTime.Builder(Java 17+)
💡 Spring Boot 中体现:@ConfigurationProperties自动绑定就是建造者思想
🔹 5. 适配器模式(Adapter)—— 接口转换
适用场景:接入第三方 SDK(微信、支付宝)、旧系统兼容
/**
* 旧版支付接口(第三方系统)
*/
interface OldPaymentSystem {
void doPay(String userId, double money);
}
/**
* 旧版微信支付实现
*/
class WeChatOldSystem implements OldPaymentSystem {
@Override
public void doPay(String userId, double money) {
System.out.println("【旧版】微信支付用户:" + userId + ",金额:" + money);
}
}
/**
* 新版统一支付接口(我们系统要使用的)
*/
interface NewPaymentService {
boolean pay(String userId, double amount, String channel);
}
/**
* 适配器:将旧接口适配为新接口
*/
class OldToNewAdapter implements NewPaymentService {
private final OldPaymentSystem oldSystem; // 持有旧系统实例
public OldToNewAdapter(OldPaymentSystem oldSystem) {
this.oldSystem = oldSystem;
}
@Override
public boolean pay(String userId, double amount, String channel) {
// 适配:将新接口参数转换为旧接口参数
if ("wechat".equals(channel)) {
oldSystem.doPay(userId, amount);
return true;
}
return false;
}
}
// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
// 假设我们接入了旧版微信支付系统
OldPaymentSystem oldSystem = new WeChatOldSystem();
// 用适配器包装,让旧系统能被新接口使用
NewPaymentService paymentService = new OldToNewAdapter(oldSystem);
// 现在所有支付都走新接口,无需修改业务逻辑
boolean result = paymentService.pay("U1001", 199.9, "wechat");
// 输出:【旧版】微信支付用户:U1001,金额:199.9
System.out.println("支付结果:" + result);
}
}
✅ Spring 中体现:
org.springframework.web.client.RestTemplate是对 HTTP 客户端的适配
💡 实际应用:公司从阿里云短信服务切换到腾讯云,只需写一个适配器,业务层无需改!
🔹 6. 装饰器模式(Decorator)—— 动态增强功能
适用场景:日志、缓存、权限、加密、限流等横切关注点
/**
* 文件输出流接口(被装饰者)
*/
interface OutputStream {
void write(String data);
}
/**
* 真实的文件输出实现
*/
class FileOutputStream implements OutputStream {
@Override
public void write(String data) {
System.out.println("💾 写入文件:" + data);
}
}
/**
* 装饰器基类:持有被装饰对象
*/
abstract class OutputStreamDecorator implements OutputStream {
protected OutputStream target;
public OutputStreamDecorator(OutputStream target) {
this.target = target;
}
@Override
public void write(String data) {
target.write(data); // 默认行为
}
}
/**
* 日志装饰器:在写入前记录日志
*/
class LoggingDecorator extends OutputStreamDecorator {
public LoggingDecorator(OutputStream target) {
super(target);
}
@Override
public void write(String data) {
System.out.println("📝 记录日志:即将写入数据 → " + data);
super.write(data); // 调用被装饰对象
}
}
/**
* 缓存装饰器:写入前先缓存
*/
class CacheDecorator extends OutputStreamDecorator {
public CacheDecorator(OutputStream target) {
super(target);
}
@Override
public void write(String data) {
System.out.println("⚡ 缓存数据:" + data);
super.write(data);
}
}
// 使用示例:动态组合多个装饰器
public class DecoratorDemo {
public static void main(String[] args) {
// 原始对象
OutputStream fileStream = new FileOutputStream();
// 一层层装饰:先加缓存,再加日志
OutputStream decorated = new LoggingDecorator(new CacheDecorator(fileStream));
// 调用一次,触发多个增强功能
decorated.write("用户登录成功");
// 输出:
// ⚡ 缓存数据:用户登录成功
// 📝 记录日志:即将写入数据 → 用户登录成功
// 💾 写入文件:用户登录成功
}
}
✅ Java 标准库:
BufferedInputStream、DataInputStream、PrintStream都是装饰器
✅ Spring AOP 就是装饰器模式的高级实现
💡 实际应用:在 Controller 层加@Cacheable、@Log、@RateLimit就是装饰器思想
🔹 7. 代理模式(Proxy)—— 控制访问
适用场景:AOP、远程调用、懒加载、权限控制
/**
* 用户服务接口
*/
interface UserService {
void getUserInfo(String userId);
void updateUser(String userId, String name);
}
/**
* 真实实现
*/
class UserServiceImpl implements UserService {
@Override
public void getUserInfo(String userId) {
System.out.println("🔍 查询用户信息:ID=" + userId);
}
@Override
public void updateUser(String userId, String name) {
System.out.println("✏️ 更新用户信息:ID=" + userId + ", 新姓名=" + name);
}
}
/**
* 代理类:控制对真实对象的访问
*/
class UserServiceProxy implements UserService {
private UserService realService; // 真实对象
public UserServiceProxy() {
this.realService = new UserServiceImpl(); // 懒加载
}
@Override
public void getUserInfo(String userId) {
// 增强:权限检查
if (!hasPermission(userId)) {
System.out.println("🚫 权限不足,无法查询用户信息");
return;
}
System.out.println("🔐 代理:在查询前做权限校验");
realService.getUserInfo(userId); // 调用真实对象
}
@Override
public void updateUser(String userId, String name) {
// 增强:日志记录
System.out.println("📝 代理:记录更新操作,用户=" + userId);
realService.updateUser(userId, name);
}
// 模拟权限检查
private boolean hasPermission(String userId) {
return "admin".equals(userId) || "U1001".equals(userId);
}
}
// 使用示例
public class ProxyDemo {
public static void main(String[] args) {
UserService proxy = new UserServiceProxy();
// 正常用户
proxy.getUserInfo("U1001"); // ✅ 通过
// 输出:
// 🔐 代理:在查询前做权限校验
// 🔍 查询用户信息:ID=U1001
// 非法用户
proxy.getUserInfo("guest"); // ❌ 拒绝
// 输出:
// 🚫 权限不足,无法查询用户信息
// 更新操作
proxy.updateUser("U1001", "张三");
// 输出:
// 📝 代理:记录更新操作,用户=U1001
// ✏️ 更新用户信息:ID=U1001, 新姓名=张三
}
}
✅ Spring AOP 就是动态代理的实现(JDK Proxy / CGLIB)
💡 实际应用:@Transactional、@Cacheable、@PreAuthorize都是代理增强
🔹 8. 外观模式(Facade)—— 统一复杂子系统接口
适用场景:微服务调用多个内部服务、封装复杂 API
/**
* 子系统1:订单服务
*/
class OrderService {
public void createOrder(String userId) {
System.out.println("📦 创建订单,用户:" + userId);
}
}
/**
* 子系统2:库存服务
*/
class InventoryService {
public boolean checkStock(String productId) {
System.out.println("📊 检查商品库存,商品ID:" + productId);
return true;
}
public void deductStock(String productId) {
System.out.println("📉 扣减库存,商品ID:" + productId);
}
}
/**
* 子系统3:支付服务
*/
class PaymentService {
public boolean pay(String orderId, double amount) {
System.out.println("💳 支付订单,订单ID:" + orderId + ",金额:" + amount);
return true;
}
}
/**
* 外观类:为复杂子系统提供统一入口
*/
class OrderFacade {
private OrderService orderService = new OrderService();
private InventoryService inventoryService = new InventoryService();
private PaymentService paymentService = new PaymentService();
// 一键下单:封装复杂流程
public void placeOrder(String userId, String productId, double amount) {
System.out.println("🚀 开始下单流程...");
// 1. 检查库存
if (!inventoryService.checkStock(productId)) {
System.out.println("❌ 库存不足,下单失败");
return;
}
// 2. 创建订单
orderService.createOrder(userId);
// 3. 扣库存
inventoryService.deductStock(productId);
// 4. 支付
if (paymentService.pay("ORD" + System.currentTimeMillis(), amount)) {
System.out.println("🎉 下单成功!");
} else {
System.out.println("❌ 支付失败,订单已取消");
}
}
}
// 使用示例
public class FacadeDemo {
public static void main(String[] args) {
// 客户端只需调用一个接口,无需关心内部细节
OrderFacade facade = new OrderFacade();
facade.placeOrder("U1001", "P001", 199.9);
// 输出:
// 🚀 开始下单流程...
// 📊 检查商品库存,商品ID:P001
// 📦 创建订单,用户:U1001
// 📉 扣减库存,商品ID:P001
// 💳 支付订单,订单ID:ORD1717000000000,金额:199.9
// 🎉 下单成功!
}
}
✅ Spring 中体现:
RestTemplate、FeignClient就是外观模式
💡 实际应用:封装“用户注册”流程(调用短信、邮箱、用户中心、积分系统)
🔹 9. 策略模式(Strategy)—— 算法可互换
适用场景:支付方式、折扣规则、排序策略、路由算法
/**
* 折扣策略接口
*/
interface DiscountStrategy {
double calculate(double originalPrice);
}
/**
* 无折扣策略
*/
class NoDiscount implements DiscountStrategy {
@Override
public double calculate(double originalPrice) {
return originalPrice; // 不打折
}
}
/**
* 8折优惠策略
*/
class EightyPercentDiscount implements DiscountStrategy {
@Override
public double calculate(double originalPrice) {
return originalPrice * 0.8;
}
}
/**
* 满减策略:满100减20
*/
class FullReductionDiscount implements DiscountStrategy {
private final double fullAmount;
private final double reduceAmount;
public FullReductionDiscount(double fullAmount, double reduceAmount) {
this.fullAmount = fullAmount;
this.reduceAmount = reduceAmount;
}
@Override
public double calculate(double originalPrice) {
if (originalPrice >= fullAmount) {
return originalPrice - reduceAmount;
}
return originalPrice;
}
}
/**
* 折扣计算器(上下文)
*/
class DiscountCalculator {
private DiscountStrategy strategy; // 策略对象
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double calculate(double price) {
if (strategy == null) {
throw new IllegalStateException("请先设置折扣策略");
}
return strategy.calculate(price);
}
}
// 使用示例:动态切换策略
public class StrategyDemo {
public static void main(String[] args) {
DiscountCalculator calc = new DiscountCalculator();
// 场景1:会员8折
calc.setStrategy(new EightyPercentDiscount());
System.out.println("会员价:" + calc.calculate(100)); // 输出:80.0
// 场景2:满100减20
calc.setStrategy(new FullReductionDiscount(100, 20));
System.out.println("满减价:" + calc.calculate(120)); // 输出:100.0
// 场景3:普通用户
calc.setStrategy(new NoDiscount());
System.out.println("原价:" + calc.calculate(80)); // 输出:80.0
}
}
✅ Spring 中体现:
Comparator、TaskExecutor、MessageConverter
💡 进阶建议:用Map<String, DiscountStrategy>+ 注解 + Spring 容器自动注入,实现热插拔!
🔹 10. 模板方法模式(Template Method)—— 固定流程,灵活步骤
适用场景:订单处理、审核流程、数据导入导出
/**
* 抽象订单处理流程(模板方法)
*/
abstract class OrderProcessTemplate {
// 模板方法:定义算法骨架,子类重写具体步骤
public final void processOrder(String orderId) {
System.out.println("📦 开始处理订单:" + orderId);
validateOrder(orderId); // 步骤1:校验
calculateTotal(orderId); // 步骤2:计算金额
applyDiscount(orderId); // 步骤3:应用折扣(子类实现)
saveOrder(orderId); // 步骤4:保存
notifyUser(orderId); // 步骤5:通知
System.out.println("✅ 订单处理完成\n");
}
// 具体方法:所有子类共享
protected void validateOrder(String orderId) {
System.out.println("🔧 步骤1:校验订单是否存在");
}
protected void calculateTotal(String orderId) {
System.out.println("💰 步骤2:计算订单总金额");
}
// 抽象方法:子类必须实现
protected abstract void applyDiscount(String orderId);
protected void saveOrder(String orderId) {
System.out.println("💾 步骤4:保存订单到数据库");
}
protected void notifyUser(String orderId) {
System.out.println("📢 步骤5:发送短信通知用户");
}
}
/**
* 普通订单处理流程
*/
class RegularOrderProcess extends OrderProcessTemplate {
@Override
protected void applyDiscount(String orderId) {
System.out.println("📉 步骤3:普通订单无折扣");
}
}
/**
* VIP订单处理流程
*/
class VIPOrderProcess extends OrderProcessTemplate {
@Override
protected void applyDiscount(String orderId) {
System.out.println("🎁 步骤3:VIP订单享受9折优惠");
}
}
// 使用示例
public class TemplateDemo {
public static void main(String[] args) {
OrderProcessTemplate regular = new RegularOrderProcess();
OrderProcessTemplate vip = new VIPOrderProcess();
regular.processOrder("ORD001");
// 输出:
// 📦 开始处理订单:ORD001
// 🔧 步骤1:校验订单是否存在
// 💰 步骤2:计算订单总金额
// 📉 步骤3:普通订单无折扣
// 💾 步骤4:保存订单到数据库
// 📢 步骤5:发送短信通知用户
// ✅ 订单处理完成
vip.processOrder("ORD002");
// 输出:
// 📦 开始处理订单:ORD002
// 🔧 步骤1:校验订单是否存在
// 💰 步骤2:计算订单总金额
// 🎁 步骤3:VIP订单享受9折优惠
// 💾 步骤4:保存订单到数据库
// 📢 步骤5:发送短信通知用户
// ✅ 订单处理完成
}
}
✅ Spring 中体现:
JdbcTemplate、AbstractRoutingDataSource
💡 实际应用:所有“审核流程”、“导入流程”、“数据清洗流程”都可用模板方法
🔹 11. 观察者模式(Observer)—— 事件驱动,解耦发布与订阅
适用场景:订单创建后发短信、发邮件、记日志、更新缓存
import java.util.ArrayList;
import java.util.List;
/**
* 观察者接口
*/
interface OrderObserver {
void onOrderCreated(String orderId);
}
/**
* 发短信观察者
*/
class SmsObserver implements OrderObserver {
@Override
public void onOrderCreated(String orderId) {
System.out.println("📱 发送短信:订单 " + orderId + " 创建成功");
}
}
/**
* 发邮件观察者
*/
class EmailObserver implements OrderObserver {
@Override
public void onOrderCreated(String orderId) {
System.out.println("📧 发送邮件:订单 " + orderId + " 创建成功");
}
}
/**
* 记录日志观察者
*/
class LogObserver implements OrderObserver {
@Override
public void onOrderCreated(String orderId) {
System.out.println("📝 记录日志:订单 " + orderId + " 已创建");
}
}
/**
* 订单发布者(被观察者)
*/
class OrderPublisher {
private List<OrderObserver> observers = new ArrayList<>();
// 注册观察者
public void addObserver(OrderObserver observer) {
observers.add(observer);
}
// 移除观察者
public void removeObserver(OrderObserver observer) {
observers.remove(observer);
}
// 通知所有观察者
public void notifyObservers(String orderId) {
System.out.println("🔔 订单创建事件触发,通知所有观察者...");
for (OrderObserver observer : observers) {
observer.onOrderCreated(orderId);
}
}
// 创建订单(触发事件)
public void createOrder(String orderId) {
System.out.println("🛒 创建订单:" + orderId);
notifyObservers(orderId); // 通知所有观察者
}
}
// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
OrderPublisher publisher = new OrderPublisher();
// 注册多个观察者
publisher.addObserver(new SmsObserver());
publisher.addObserver(new EmailObserver());
publisher.addObserver(new LogObserver());
// 创建订单,自动触发通知
publisher.createOrder("ORD20240501");
// 输出:
// 🛒 创建订单:ORD20240501
// 🔔 订单创建事件触发,通知所有观察者...
// 📱 发送短信:订单 ORD20240501 创建成功
// 📧 发送邮件:订单 ORD20240501 创建成功
// 📝 记录日志:订单 ORD20240501 已创建
}
}
✅ Spring 中体现:
ApplicationEventPublisher+@EventListener
💡 实际应用:Spring Boot 中@EventListener(OrderCreatedEvent.class)就是观察者模式
🔹 12. 责任链模式(Chain of Responsibility)—— 多级处理,逐级传递
适用场景:权限校验、风控过滤、日志拦截、API 网关
/**
* 处理器接口
*/
interface RequestHandler {
void handle(String request);
void setNext(RequestHandler next); // 设置下一个处理器
}
/**
* 权限校验处理器
*/
class AuthHandler implements RequestHandler {
private RequestHandler next;
@Override
public void handle(String request) {
System.out.println("🔒 权限校验:检查用户是否登录");
if (request.contains("admin")) {
System.out.println("✅ 权限通过");
if (next != null) next.handle(request); // 传递给下一个
} else {
System.out.println("❌ 权限不足,拒绝请求");
}
}
@Override
public void setNext(RequestHandler next) {
this.next = next;
}
}
/**
* 黑名单过滤处理器
*/
class BlacklistHandler implements RequestHandler {
private RequestHandler next;
@Override
public void handle(String request) {
System.out.println("⛔ 黑名单检查:检查IP是否被封禁");
if (!request.contains("blocked")) {
System.out.println("✅ 未在黑名单");
if (next != null) next.handle(request);
} else {
System.out.println("🚫 请求被拦截,来自黑名单IP");
}
}
@Override
public void setNext(RequestHandler next) {
this.next = next;
}
}
/**
* 日志记录处理器
*/
class LogHandler implements RequestHandler {
private RequestHandler next;
@Override
public void handle(String request) {
System.out.println("📝 记录请求日志:" + request);
if (next != null) next.handle(request);
}
@Override
public void setNext(RequestHandler next) {
this.next = next;
}
}
// 使用示例:构建责任链
public class ChainDemo {
public static void main(String[] args) {
// 构建责任链:权限 → 黑名单 → 日志
RequestHandler auth = new AuthHandler();
RequestHandler blacklist = new BlacklistHandler();
RequestHandler log = new LogHandler();
auth.setNext(blacklist);
blacklist.setNext(log);
// 模拟请求
auth.handle("admin:query"); // 权限通过 → 黑名单通过 → 日志记录
// 输出:
// 🔒 权限校验:检查用户是否登录
// ✅ 权限通过
// ⛔ 黑名单检查:检查IP是否被封禁
// ✅ 未在黑名单
// 📝 记录请求日志:admin:query
System.out.println("\n--- 另一个请求 ---\n");
auth.handle("blocked:delete"); // 权限通过 → 黑名单拦截 → 停止
// 输出:
// 🔒 权限校验:检查用户是否登录
// ✅ 权限通过
// ⛔ 黑名单检查:检查IP是否被封禁
// 🚫 请求被拦截,来自黑名单IP
}
}
✅ Spring 中体现:
Filter、Interceptor、GatewayFilter
💡 实际应用:Spring Security 的FilterChain、API 网关的鉴权链
🔹 13. 命令模式(Command)—— 将请求封装为对象
适用场景:操作回滚、异步任务、MQ 消息、宏命令
/**
* 命令接口
*/
interface Command {
void execute(); // 执行
void undo(); // 撤销
}
/**
* 发送短信命令
*/
class SendSmsCommand implements Command {
private String phone;
private String message;
public SendSmsCommand(String phone, String message) {
this.phone = phone;
this.message = message;
}
@Override
public void execute() {
System.out.println("📱 发送短信到 " + phone + ": " + message);
}
@Override
public void undo() {
System.out.println("❌ 撤销短信发送: " + message);
}
}
/**
* 扣减库存命令
*/
class DeductInventoryCommand implements Command {
private String productId;
private int quantity;
public DeductInventoryCommand(String productId, int quantity) {
this.productId = productId;
this.quantity = quantity;
}
@Override
public void execute() {
System.out.println("📉 扣减库存:商品 " + productId + ",数量 " + quantity);
}
@Override
public void undo() {
System.out.println("📈 恢复库存:商品 " + productId + ",数量 " + quantity);
}
}
/**
* 命令执行器(Invoker)
*/
class CommandExecutor {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void execute() {
if (command != null) {
command.execute();
}
}
public void undo() {
if (command != null) {
command.undo();
}
}
}
// 使用示例
public class CommandDemo {
public static void main(String[] args) {
CommandExecutor executor = new CommandExecutor();
// 创建命令
Command smsCmd = new SendSmsCommand("13800138000", "您的订单已创建");
Command inventoryCmd = new DeductInventoryCommand("P001", 2);
// 执行命令
executor.setCommand(smsCmd);
executor.execute(); // 📱 发送短信...
executor.undo(); // ❌ 撤销...
System.out.println("---");
// 执行库存扣减
executor.setCommand(inventoryCmd);
executor.execute(); // 📉 扣减库存...
executor.undo(); // 📈 恢复库存...
}
}
✅ Spring 中体现:
@Async、@RabbitListener、Runnable
💡 实际应用:MQ 消息消费就是“命令模式”:消息 = 命令,消费者 = 执行器
🔹 14. 状态模式(State)—— 对象行为随状态改变
适用场景:订单状态、合同状态、流程审批、游戏状态机
/**
* 订单状态接口
*/
interface OrderState {
void next(OrderContext context); // 下一状态
void prev(OrderContext context); // 上一状态
String getStatusName();
}
/**
* 待支付状态
*/
class PendingPaymentState implements OrderState {
@Override
public void next(OrderContext context) {
System.out.println("✅ 支付成功,订单进入【已支付】状态");
context.setState(new PaidState());
}
@Override
public void prev(OrderContext context) {
System.out.println("❌ 无法退回上一状态");
}
@Override
public String getStatusName() {
return "待支付";
}
}
/**
* 已支付状态
*/
class PaidState implements OrderState {
@Override
public void next(OrderContext context) {
System.out.println("✅ 订单进入【已发货】状态");
context.setState(new ShippedState());
}
@Override
public void prev(OrderContext context) {
System.out.println("🔙 订单退回【待支付】状态");
context.setState(new PendingPaymentState());
}
@Override
public String getStatusName() {
return "已支付";
}
}
/**
* 已发货状态
*/
class ShippedState implements OrderState {
@Override
public void next(OrderContext context) {
System.out.println("✅ 订单进入【已完成】状态");
context.setState(new CompletedState());
}
@Override
public void prev(OrderContext context) {
System.out.println("🔙 订单退回【已支付】状态");
context.setState(new PaidState());
}
@Override
public String getStatusName() {
return "已发货";
}
}
/**
* 已完成状态
*/
class CompletedState implements OrderState {
@Override
public void next(OrderContext context) {
System.out.println("❌ 订单已完成,无法继续流转");
}
@Override
public void prev(OrderContext context) {
System.out.println("🔙 订单退回【已发货】状态");
context.setState(new ShippedState());
}
@Override
public String getStatusName() {
return "已完成";
}
}
/**
* 订单上下文(持有当前状态)
*/
class OrderContext {
private OrderState state;
public OrderContext() {
this.state = new PendingPaymentState(); // 初始状态
}
public void setState(OrderState state) {
this.state = state;
System.out.println("🔄 当前状态变更为:" + state.getStatusName());
}
public void next() {
state.next(this);
}
public void prev() {
state.prev(this);
}
public String getCurrentState() {
return state.getStatusName();
}
}
// 使用示例
public class StateDemo {
public static void main(String[] args) {
OrderContext order = new OrderContext();
System.out.println("初始状态:" + order.getCurrentState());
order.next(); // 待支付 → 已支付
order.next(); // 已支付 → 已发货
order.next(); // 已发货 → 已完成
order.next(); // 无法继续
System.out.println("---");
order.prev(); // 已完成 → 已发货
order.prev(); // 已发货 → 已支付
order.prev(); // 已支付 → 待支付
}
}
✅ Spring 中体现:
Spring StateMachine
💡 实际应用:订单系统、合同系统、审批流(如钉钉审批)
🔹 15. 外观模式(Facade)—— 已在第8节详解,不再重复
✅ 补充说明:在微服务架构中,网关(Gateway) 就是典型的外观模式!
✅ 三、总结:后端开发者必掌握的15种设计模式速查表
| 模式 | 类型 | 是否必须掌握 | 实际应用场景 | 代码难度 |
|---|---|---|---|---|
| 单例 | 创建型 | ✅ | 连接池、配置中心 | ⭐ |
| 工厂方法 | 创建型 | ✅ | 支付方式、日志输出 | ⭐⭐ |
| 抽象工厂 | 创建型 | ✅ | 多数据库组合 | ⭐⭐⭐ |
| 建造者 | 创建型 | ✅ | 构建复杂对象(SQL/DTO) | ⭐⭐ |
| 适配器 | 结构型 | ✅ | 第三方SDK兼容 | ⭐⭐ |
| 装饰器 | 结构型 | ✅ | 日志、缓存、AOP | ⭐⭐⭐ |
| 代理 | 结构型 | ✅ | Spring AOP、远程调用 | ⭐⭐⭐ |
| 外观 | 结构型 | ✅ | 微服务封装、统一接口 | ⭐⭐ |
| 策略 | 行为型 | ✅ | 支付、折扣、排序 | ⭐⭐ |
| 模板方法 | 行为型 | ✅ | 订单流程、审核流程 | ⭐⭐ |
| 观察者 | 行为型 | ✅ | 事件通知、异步解耦 | ⭐⭐⭐ |
| 责任链 | 行为型 | ✅ | 权限校验、风控过滤 | ⭐⭐⭐ |
| 命令 | 行为型 | ✅ | 操作回滚、MQ 消息 | ⭐⭐⭐ |
| 状态 | 行为型 | ✅ | 订单状态、审批流 | ⭐⭐⭐ |
| 原型 | 创建型 | ⚠️ | 了解即可 | ⭐ |
🚀 建议学习顺序:
单例 → 工厂 → 策略 → 模板 → 装饰器 → 代理 → 观察者 → 责任链 → 命令 → 状态
✅ 四、实战建议:如何在项目中落地?
| 阶段 | 行动建议 |
|---|---|
| 🚀 第1周 | 在你的 Spring Boot 项目中,把 if-else 支付方式判断,重构为策略模式 |
| 🚀 第2周 | 把日志打印、权限校验、限流逻辑,用装饰器或AOP封装 |
| 🚀 第3周 | 用模板方法重构一个“订单创建流程” |
| 🚀 第4周 | 用观察者实现“订单创建后发短信” |
| 🚀 第5周 | 用状态模式实现“订单状态流转” |
✅ 终极目标:让你的代码可读、可扩展、可测试、易维护!
📎 附录:完整代码包获取建议
所有示例代码均已可运行,建议你:
- 在 IDEA 中新建一个 Maven 项目
- 将以上每个模式的代码放入独立类中
- 用
main()方法运行测试- 每学一个模式,写一篇笔记,发到团队知识库!
💬 最后寄语
设计模式不是为了“炫技”,而是为了“少改代码”。
你今天用一个策略模式,明天就不必改 10 个 if-else。
你今天用一个观察者,明天加个通知功能,无需动核心逻辑。真正的高手,不是写得多,而是改得少。
687

被折叠的 条评论
为什么被折叠?



