3、Java 后端开发者必学设计模式实战手册

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

📘 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 标准库StringBuilderStringJoinerjava.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 标准库BufferedInputStreamDataInputStreamPrintStream 都是装饰器
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 中体现RestTemplateFeignClient 就是外观模式
💡 实际应用:封装“用户注册”流程(调用短信、邮箱、用户中心、积分系统)


🔹 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 中体现ComparatorTaskExecutorMessageConverter
💡 进阶建议:用 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 中体现JdbcTemplateAbstractRoutingDataSource
💡 实际应用:所有“审核流程”、“导入流程”、“数据清洗流程”都可用模板方法


🔹 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 中体现FilterInterceptorGatewayFilter
💡 实际应用: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@RabbitListenerRunnable
💡 实际应用: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周状态模式实现“订单状态流转”

终极目标:让你的代码可读、可扩展、可测试、易维护


📎 附录:完整代码包获取建议

所有示例代码均已可运行,建议你:

  1. 在 IDEA 中新建一个 Maven 项目
  2. 将以上每个模式的代码放入独立类中
  3. main() 方法运行测试
  4. 每学一个模式,写一篇笔记,发到团队知识库!

💬 最后寄语

设计模式不是为了“炫技”,而是为了“少改代码”。
你今天用一个策略模式,明天就不必改 10 个 if-else。
你今天用一个观察者,明天加个通知功能,无需动核心逻辑。

真正的高手,不是写得多,而是改得少。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值