设计模式:实战概要

目录

[一、 创建型模式:解决对象创建的复杂问题](#一、 创建型模式:解决对象创建的复杂问题)

[1. 单例模式:全局配置管理(无人售货柜项目)](#1. 单例模式:全局配置管理(无人售货柜项目))

场景痛点

解决方案:懒汉式单例(双重检查锁,线程安全)

应用效果

框架关联

[2. 工厂方法模式:支付方式适配(电商项目)](#2. 工厂方法模式:支付方式适配(电商项目))

场景痛点

解决方案:工厂方法模式(定义支付工厂,子类实现具体支付方式)

[步骤 1:定义抽象产品(支付接口)](#步骤 1:定义抽象产品(支付接口))

[步骤 2:实现具体产品(各支付方式)](#步骤 2:实现具体产品(各支付方式))

[步骤 3:定义抽象工厂 + 具体工厂](#步骤 3:定义抽象工厂 + 具体工厂)

[步骤 4:业务层调用(无需关注具体实现)](#步骤 4:业务层调用(无需关注具体实现))

应用效果

[二、 结构型模式:优化代码结构,降低耦合](#二、 结构型模式:优化代码结构,降低耦合)

[1. 代理模式:接口权限控制(无人售货柜后台)](#1. 代理模式:接口权限控制(无人售货柜后台))

场景痛点

[解决方案:动态代理模式(JDK 动态代理,AOP 思想)](#解决方案:动态代理模式(JDK 动态代理,AOP 思想))

[步骤 1:定义业务接口](#步骤 1:定义业务接口)

[步骤 2:实现目标对象(真实业务逻辑)](#步骤 2:实现目标对象(真实业务逻辑))

[步骤 3:实现代理类(权限校验逻辑)](#步骤 3:实现代理类(权限校验逻辑))

[步骤 4:业务层使用代理](#步骤 4:业务层使用代理)

应用效果

框架关联

[2. 装饰器模式:IO 流增强(无人售货柜日志模块)](#2. 装饰器模式:IO 流增强(无人售货柜日志模块))

场景痛点

解决方案:装饰器模式(动态给日志对象添加功能)

[步骤 1:定义抽象组件(日志接口)](#步骤 1:定义抽象组件(日志接口))

[步骤 2:实现基础组件(本地文件日志)](#步骤 2:实现基础组件(本地文件日志))

[步骤 3:实现装饰器(增强功能)](#步骤 3:实现装饰器(增强功能))

[步骤 4:业务层组合装饰器](#步骤 4:业务层组合装饰器)

应用效果

框架关联

[三、 行为型模式:规范对象交互,提升逻辑灵活性](#三、 行为型模式:规范对象交互,提升逻辑灵活性)

[1. 策略模式:订单价格计算(电商项目)](#1. 策略模式:订单价格计算(电商项目))

场景痛点

解决方案:策略模式(封装不同优惠策略,动态切换)

[步骤 1:定义策略接口](#步骤 1:定义策略接口)

[步骤 2:实现具体策略](#步骤 2:实现具体策略)

[步骤 3:策略上下文(统一调用入口)](#步骤 3:策略上下文(统一调用入口))

[步骤 4:业务层调用](#步骤 4:业务层调用)

应用效果

[2. 命令模式:设备指令下发(无人售货柜项目)](#2. 命令模式:设备指令下发(无人售货柜项目))

场景痛点

解决方案:命令模式(封装指令为对象,解耦指令发送者与执行者)

[步骤 1:定义抽象命令](#步骤 1:定义抽象命令)

[步骤 2:实现具体命令](#步骤 2:实现具体命令)

[步骤 3:实现命令调用者(指令管理器)](#步骤 3:实现命令调用者(指令管理器))

[步骤 4:控制器调用](#步骤 4:控制器调用)

应用效果

[四、 设计模式选型核心思路](#四、 设计模式选型核心思路)

[五、 总结](#五、 总结)


设计模式的价值在于解决真实业务场景中的耦合、扩展、复用问题 。本文结合电商订单、无人售货柜、支付系统 等真实项目场景,拆解常用设计模式的落地思路与代码实现,聚焦 "为什么用 ""怎么用 ""解决什么问题" 三大核心。

一、 创建型模式:解决对象创建的复杂问题

创建型模式的核心目标是封装对象创建细节,让调用方无需关注初始化逻辑,提升创建灵活性。

1. 单例模式:全局配置管理(无人售货柜项目)

场景痛点

无人售货柜项目中,DeviceConfig 包含设备的串口配置、网络参数、货道信息等全局配置,全系统需共享同一实例,且初始化时需从本地文件加载配置,避免重复 IO 操作。

解决方案:懒汉式单例(双重检查锁,线程安全)

java

运行

复制代码
/**
 * 售货柜设备配置(单例模式)
 * 核心:全局唯一实例 + 延迟初始化 + 线程安全
 */
public class DeviceConfig {
    // 1. 私有静态变量(volatile 禁止指令重排)
    private static volatile DeviceConfig instance;
    // 配置参数
    private String serialPort; // 串口地址
    private int baudRate;      // 波特率
    private Map<Integer, String> channelMap; // 货道映射

    // 2. 私有构造器(禁止外部new)
    private DeviceConfig() {
        // 从本地配置文件加载参数(实际项目用Properties/YAML)
        loadConfigFromFile();
    }

    // 3. 公共静态方法(双重检查锁,懒加载)
    public static DeviceConfig getInstance() {
        if (instance == null) { // 第一次检查:避免不必要的锁
            synchronized (DeviceConfig.class) { // 加锁
                if (instance == null) { // 第二次检查:防止多线程重复创建
                    instance = new DeviceConfig();
                }
            }
        }
        return instance;
    }

    // 加载配置文件
    private void loadConfigFromFile() {
        // 实际逻辑:读取config/device.properties
        this.serialPort = "/dev/ttyUSB0";
        this.baudRate = 9600;
        this.channelMap = new HashMap<>();
        channelMap.put(1, "可乐");
        channelMap.put(2, "薯片");
    }

    // getter方法
    public String getSerialPort() { return serialPort; }
    public Map<Integer, String> getChannelMap() { return channelMap; }
}
应用效果
  • 全系统共享同一配置实例,避免重复加载文件导致的性能损耗;
  • 延迟初始化:首次调用 getInstance() 才加载配置,减少项目启动时间;
  • 线程安全:双重检查锁保证多线程环境下不会创建多个实例。
框架关联

Spring 容器中的 默认 Bean 是单例模式 ,底层通过 DefaultSingletonBeanRegistry 实现,原理与上述案例一致。

2. 工厂方法模式:支付方式适配(电商项目)

场景痛点

电商订单支付模块需支持微信支付、支付宝、银联 三种方式,后续可能新增 "云闪付"。若直接在业务代码中用 if-else 判断支付类型,会导致代码臃肿、扩展困难(新增支付方式需修改原有代码,违反开闭原则)。

解决方案:工厂方法模式(定义支付工厂,子类实现具体支付方式)
步骤 1:定义抽象产品(支付接口)

java

运行

复制代码
/**
 * 抽象支付产品
 */
public interface Payment {
    // 发起支付
    String pay(String orderId, BigDecimal amount);
    // 查询支付状态
    boolean queryPayStatus(String orderId);
}
步骤 2:实现具体产品(各支付方式)

java

运行

复制代码
// 微信支付实现
public class WechatPayment implements Payment {
    @Override
    public String pay(String orderId, BigDecimal amount) {
        // 调用微信支付SDK
        return "微信支付下单成功,订单号:" + orderId + ",金额:" + amount;
    }

    @Override
    public boolean queryPayStatus(String orderId) {
        return true; // 模拟查询结果
    }
}

// 支付宝支付实现
public class AlipayPayment implements Payment {
    @Override
    public String pay(String orderId, BigDecimal amount) {
        return "支付宝支付下单成功,订单号:" + orderId + ",金额:" + amount;
    }

    @Override
    public boolean queryPayStatus(String orderId) {
        return true;
    }
}
步骤 3:定义抽象工厂 + 具体工厂

java

运行

复制代码
/**
 * 抽象支付工厂
 */
public interface PaymentFactory {
    Payment createPayment();
}

// 微信支付工厂
public class WechatPaymentFactory implements PaymentFactory {
    @Override
    public Payment createPayment() {
        return new WechatPayment();
    }
}

// 支付宝支付工厂
public class AlipayPaymentFactory implements PaymentFactory {
    @Override
    public Payment createPayment() {
        return new AlipayPayment();
    }
}
步骤 4:业务层调用(无需关注具体实现)

java

运行

复制代码
@Service
public class OrderPayService {
    // 根据支付类型获取工厂,创建支付实例
    public String doPay(String orderId, BigDecimal amount, String payType) {
        PaymentFactory factory;
        switch (payType) {
            case "WECHAT":
                factory = new WechatPaymentFactory();
                break;
            case "ALIPAY":
                factory = new AlipayPaymentFactory();
                break;
            default:
                throw new IllegalArgumentException("不支持的支付类型");
        }
        Payment payment = factory.createPayment();
        return payment.pay(orderId, amount);
    }
}
应用效果
  • 开闭原则 :新增 "云闪付" 只需添加 CloudPaymentCloudPaymentFactory,无需修改原有业务代码;
  • 职责单一:每种支付方式的逻辑封装在独立类中,便于维护和测试;
  • 解耦 :业务层只依赖 Payment 接口,不依赖具体实现类。

二、 结构型模式:优化代码结构,降低耦合

结构型模式的核心目标是通过类 / 对象的组合,解决结构臃肿、扩展困难的问题

1. 代理模式:接口权限控制(无人售货柜后台)

场景痛点

无人售货柜后台的 DeviceManageService 包含设备重启、货道修改、参数配置 等敏感接口,需对调用方进行权限校验 (如只有管理员角色才能调用)。若直接在接口中添加权限逻辑,会导致业务逻辑与权限逻辑耦合,且重复代码多。

解决方案:动态代理模式(JDK 动态代理,AOP 思想)
步骤 1:定义业务接口

java

运行

复制代码
/**
 * 设备管理接口(被代理接口)
 */
public interface DeviceManageService {
    void restartDevice(String deviceId); // 重启设备
    void updateChannel(String deviceId, Map<Integer, String> channelMap); // 修改货道
}
步骤 2:实现目标对象(真实业务逻辑)

java

运行

复制代码
/**
 * 真实设备管理服务
 */
@Service
public class DeviceManageServiceImpl implements DeviceManageService {
    @Override
    public void restartDevice(String deviceId) {
        System.out.println("重启设备:" + deviceId);
        // 实际逻辑:发送重启指令到硬件
    }

    @Override
    public void updateChannel(String deviceId, Map<Integer, String> channelMap) {
        System.out.println("修改设备货道:" + deviceId + ",货道映射:" + channelMap);
    }
}
步骤 3:实现代理类(权限校验逻辑)

java

运行

复制代码
/**
 * 权限代理类(JDK 动态代理)
 * 核心:在不修改目标对象的前提下,增强方法功能
 */
public class PermissionProxy implements InvocationHandler {
    // 目标对象(被代理的真实对象)
    private final Object target;

    public PermissionProxy(Object target) {
        this.target = target;
    }

    /**
     * 代理方法:增强目标方法的执行逻辑
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 1. 前置增强:权限校验
        checkPermission();
        // 2. 执行目标方法
        Object result = method.invoke(target, args);
        // 3. 后置增强:记录操作日志
        logOperation(method.getName(), args);
        return result;
    }

    // 权限校验逻辑
    private void checkPermission() {
        // 实际逻辑:从 ThreadLocal 获取当前用户角色
        String role = UserContextHolder.getCurrentUser().getRole();
        if (!"ADMIN".equals(role)) {
            throw new SecurityException("无权限操作设备!");
        }
    }

    // 日志记录逻辑
    private void logOperation(String methodName, Object[] args) {
        System.out.println("执行设备操作:" + methodName + ",参数:" + Arrays.toString(args));
    }

    // 获取代理对象的工具方法
    public static Object getProxy(Object target) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new PermissionProxy(target)
        );
    }
}
步骤 4:业务层使用代理

java

运行

复制代码
@Configuration
public class DeviceConfig {
    @Bean
    public DeviceManageService deviceManageService() {
        // 创建真实对象
        DeviceManageServiceImpl target = new DeviceManageServiceImpl();
        // 生成代理对象并返回
        return (DeviceManageService) PermissionProxy.getProxy(target);
    }
}

// 控制器调用
@RestController
@RequestMapping("/device")
public class DeviceController {
    @Autowired
    private DeviceManageService deviceManageService;

    @PostMapping("/restart/{deviceId}")
    public String restart(@PathVariable String deviceId) {
        deviceManageService.restartDevice(deviceId);
        return "操作成功";
    }
}
应用效果
  • 解耦:权限校验、日志记录与业务逻辑完全分离,符合单一职责原则;
  • 可复用:代理逻辑可复用在其他需要权限控制的接口上;
  • 无侵入:无需修改目标对象的代码,只需通过代理增强功能。
框架关联

Spring AOP 的底层就是动态代理模式@Transactional@Cacheable 等注解的实现原理与上述案例一致。

2. 装饰器模式:IO 流增强(无人售货柜日志模块)

场景痛点

无人售货柜的日志模块需要记录设备操作日志,要求:

  1. 日志内容需格式化(包含时间、设备 ID、操作类型);
  2. 日志需同时写入本地文件 + 上传到云端
  3. 后续可能新增 "加密日志" 功能。若直接写一个 LogService 包含所有逻辑,会导致功能耦合、扩展困难
解决方案:装饰器模式(动态给日志对象添加功能)
步骤 1:定义抽象组件(日志接口)

java

运行

复制代码
/**
 * 抽象日志组件
 */
public interface Logger {
    void log(String deviceId, String content);
}
步骤 2:实现基础组件(本地文件日志)

java

运行

复制代码
/**
 * 基础日志组件:写入本地文件
 */
public class FileLogger implements Logger {
    @Override
    public void log(String deviceId, String content) {
        // 实际逻辑:写入本地文件 /logs/device-{deviceId}.log
        System.out.println("【本地日志】设备:" + deviceId + ",内容:" + content);
    }
}
步骤 3:实现装饰器(增强功能)

java

运行

复制代码
/**
 * 装饰器抽象类:遵循抽象组件接口,持有组件引用
 */
public abstract class LoggerDecorator implements Logger {
    protected Logger logger;

    public LoggerDecorator(Logger logger) {
        this.logger = logger;
    }
}

// 装饰器1:格式化日志(添加时间戳)
public class FormatLoggerDecorator extends LoggerDecorator {
    public FormatLoggerDecorator(Logger logger) {
        super(logger);
    }

    @Override
    public void log(String deviceId, String content) {
        // 格式化内容:[时间] 设备ID - 内容
        String formatContent = String.format("[%s] %s - %s",
                LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
                deviceId, content);
        // 调用被装饰者的方法
        logger.log(deviceId, formatContent);
    }
}

// 装饰器2:上传云端日志
public class CloudLoggerDecorator extends LoggerDecorator {
    public CloudLoggerDecorator(Logger logger) {
        super(logger);
    }

    @Override
    public void log(String deviceId, String content) {
        // 1. 先执行被装饰者的逻辑(写入本地)
        logger.log(deviceId, content);
        // 2. 新增功能:上传到云端
        uploadToCloud(deviceId, content);
    }

    private void uploadToCloud(String deviceId, String content) {
        System.out.println("【云端日志】设备:" + deviceId + ",内容:" + content);
    }
}
步骤 4:业务层组合装饰器

java

运行

复制代码
@Service
public class DeviceLogService {
    private final Logger logger;

    // 构造器注入:组合装饰器
    public DeviceLogService() {
        // 基础组件:本地日志
        Logger baseLogger = new FileLogger();
        // 装饰器1:格式化
        Logger formatLogger = new FormatLoggerDecorator(baseLogger);
        // 装饰器2:上传云端
        this.logger = new CloudLoggerDecorator(formatLogger);
    }

    public void recordLog(String deviceId, String content) {
        logger.log(deviceId, content);
    }
}

// 调用示例
deviceLogService.recordLog("DEVICE001", "货道1补货完成");
// 输出结果:
// 【本地日志】设备:DEVICE001,内容:[2025-12-26T15:30:00] DEVICE001 - 货道1补货完成
// 【云端日志】设备:DEVICE001,内容:[2025-12-26T15:30:00] DEVICE001 - 货道1补货完成
应用效果
  • 功能动态组合 :按需组合装饰器(如只需要本地日志则不加 CloudLoggerDecorator);
  • 开闭原则 :新增 "加密日志" 只需添加 EncryptLoggerDecorator,无需修改原有代码;
  • 职责单一:每个装饰器只负责一个增强功能,便于维护。
框架关联

JDK 的 IO 流是装饰器模式的经典实现 ,如 BufferedInputStream 装饰 FileInputStream,实现缓冲功能。

三、 行为型模式:规范对象交互,提升逻辑灵活性

行为型模式的核心目标是定义对象间的通信方式,解决行为协调、职责分配的问题。

1. 策略模式:订单价格计算(电商项目)

场景痛点

电商订单结算时,需根据用户等级、优惠券、促销活动计算最终价格:

  • 普通用户:原价;
  • VIP 用户:9 折;
  • 新用户:满 100 减 20;
  • 叠加优惠券:再减固定金额。若用 if-else 实现,会导致逻辑混乱、扩展困难(新增优惠类型需修改结算方法)。
解决方案:策略模式(封装不同优惠策略,动态切换)
步骤 1:定义策略接口

java

运行

复制代码
/**
 * 订单优惠策略接口
 */
public interface DiscountStrategy {
    /**
     * 计算优惠后价格
     * @param order 订单信息
     * @return 优惠后金额
     */
    BigDecimal calculate(Order order);

    /**
     * 获取策略类型
     */
    String getType();
}
步骤 2:实现具体策略

java

运行

复制代码
// 策略1:普通用户(无优惠)
public class NormalUserStrategy implements DiscountStrategy {
    @Override
    public BigDecimal calculate(Order order) {
        return order.getTotalAmount();
    }

    @Override
    public String getType() {
        return "NORMAL";
    }
}

// 策略2:VIP用户(9折)
public class VipUserStrategy implements DiscountStrategy {
    @Override
    public BigDecimal calculate(Order order) {
        return order.getTotalAmount().multiply(new BigDecimal("0.9"));
    }

    @Override
    public String getType() {
        return "VIP";
    }
}

// 策略3:新用户(满100减20)
public class NewUserStrategy implements DiscountStrategy {
    @Override
    public BigDecimal calculate(Order order) {
        BigDecimal amount = order.getTotalAmount();
        return amount.compareTo(new BigDecimal("100")) >= 0 ? amount.subtract(new BigDecimal("20")) : amount;
    }

    @Override
    public String getType() {
        return "NEW";
    }
}
步骤 3:策略上下文(统一调用入口)

java

运行

复制代码
/**
 * 策略上下文:封装策略选择逻辑,提供统一调用入口
 */
@Service
public class DiscountContext {
    // 策略容器:Spring 启动时自动注入所有策略实现类
    private final Map<String, DiscountStrategy> strategyMap;

    // 构造器注入:Spring 会自动将所有 DiscountStrategy 实现类放入 Map
    public DiscountContext(List<DiscountStrategy> strategies) {
        this.strategyMap = new HashMap<>();
        for (DiscountStrategy strategy : strategies) {
            strategyMap.put(strategy.getType(), strategy);
        }
    }

    /**
     * 计算订单最终价格
     */
    public BigDecimal calculateFinalPrice(Order order) {
        // 1. 获取用户类型对应的策略
        String userType = order.getUser().getType();
        DiscountStrategy strategy = strategyMap.getOrDefault(userType, new NormalUserStrategy());
        // 2. 计算基础优惠价格
        BigDecimal discountAmount = strategy.calculate(order);
        // 3. 叠加优惠券优惠
        if (order.getCoupon() != null) {
            discountAmount = discountAmount.subtract(order.getCoupon().getAmount());
        }
        // 4. 价格不能小于0
        return discountAmount.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : discountAmount;
    }
}
步骤 4:业务层调用

java

运行

复制代码
@Service
public class OrderService {
    @Autowired
    private DiscountContext discountContext;

    public BigDecimal checkout(Order order) {
        return discountContext.calculateFinalPrice(order);
    }
}
应用效果
  • 消除 if-else :策略选择逻辑由 strategyMap 自动完成,代码更简洁;
  • 灵活扩展 :新增 "黑钻用户 8 折" 策略,只需添加 BlackDiamondStrategy 类,无需修改原有代码;
  • 便于测试:每个策略可单独测试,降低测试复杂度。

2. 命令模式:设备指令下发(无人售货柜项目)

场景痛点

无人售货柜后台需向设备下发多种指令

  • 货道库存查询指令;
  • 设备重启指令;
  • 商品价格更新指令;要求:
  1. 指令可异步执行(无需等待设备响应);
  2. 指令可记录日志(便于排查问题);
  3. 后续可新增指令类型(如 "清库存指令")。
解决方案:命令模式(封装指令为对象,解耦指令发送者与执行者)
步骤 1:定义抽象命令

java

运行

复制代码
/**
 * 设备指令抽象命令
 */
public interface DeviceCommand {
    // 执行指令
    void execute();
    // 获取指令ID
    String getCommandId();
}
步骤 2:实现具体命令

java

运行

复制代码
/**
 * 具体命令1:库存查询指令
 */
public class StockQueryCommand implements DeviceCommand {
    private final String deviceId;
    private final DeviceClient deviceClient; // 设备通信客户端(执行者)
    private final String commandId;

    public StockQueryCommand(String deviceId, DeviceClient deviceClient) {
        this.deviceId = deviceId;
        this.deviceClient = deviceClient;
        this.commandId = "CMD_" + System.currentTimeMillis();
    }

    @Override
    public void execute() {
        // 调用执行者的方法:下发查询指令
        String result = deviceClient.sendQueryStockCommand(deviceId);
        // 记录指令执行日志
        System.out.println("执行库存查询指令:" + commandId + ",设备:" + deviceId + ",结果:" + result);
    }

    @Override
    public String getCommandId() {
        return commandId;
    }
}

/**
 * 具体命令2:价格更新指令
 */
public class PriceUpdateCommand implements DeviceCommand {
    private final String deviceId;
    private final DeviceClient deviceClient;
    private final Map<Integer, BigDecimal> priceMap; // 货道-价格映射
    private final String commandId;

    public PriceUpdateCommand(String deviceId, DeviceClient deviceClient, Map<Integer, BigDecimal> priceMap) {
        this.deviceId = deviceId;
        this.deviceClient = deviceClient;
        this.priceMap = priceMap;
        this.commandId = "CMD_" + System.currentTimeMillis();
    }

    @Override
    public void execute() {
        String result = deviceClient.sendUpdatePriceCommand(deviceId, priceMap);
        System.out.println("执行价格更新指令:" + commandId + ",设备:" + deviceId + ",结果:" + result);
    }

    @Override
    public String getCommandId() {
        return commandId;
    }
}
步骤 3:实现命令调用者(指令管理器)

java

运行

复制代码
/**
 * 命令调用者:设备指令管理器
 * 核心:触发命令执行,无需关注命令具体逻辑
 */
@Service
public class DeviceCommandInvoker {
    @Autowired
    private DeviceClient deviceClient;
    // 线程池:异步执行指令
    private final ExecutorService executor = Executors.newFixedThreadPool(5);

    /**
     * 下发库存查询指令
     */
    public String sendStockQueryCommand(String deviceId) {
        DeviceCommand command = new StockQueryCommand(deviceId, deviceClient);
        executor.submit(command::execute); // 异步执行
        return command.getCommandId();
    }

    /**
     * 下发价格更新指令
     */
    public String sendPriceUpdateCommand(String deviceId, Map<Integer, BigDecimal> priceMap) {
        DeviceCommand command = new PriceUpdateCommand(deviceId, deviceClient, priceMap);
        executor.submit(command::execute);
        return command.getCommandId();
    }
}
步骤 4:控制器调用

java

运行

复制代码
@RestController
@RequestMapping("/device/command")
public class DeviceCommandController {
    @Autowired
    private DeviceCommandInvoker commandInvoker;

    @PostMapping("/stock/{deviceId}")
    public String queryStock(@PathVariable String deviceId) {
        String commandId = commandInvoker.sendStockQueryCommand(deviceId);
        return "指令已下发,ID:" + commandId;
    }

    @PostMapping("/price/{deviceId}")
    public String updatePrice(@PathVariable String deviceId, @RequestBody Map<Integer, BigDecimal> priceMap) {
        String commandId = commandInvoker.sendPriceUpdateCommand(deviceId, priceMap);
        return "指令已下发,ID:" + commandId;
    }
}
应用效果
  • 解耦 :指令发送者(控制器)与执行者(DeviceClient)完全分离,发送者无需知道指令如何执行;
  • 异步化:通过线程池实现指令异步执行,提升系统响应速度;
  • 可扩展 :新增 "清库存指令" 只需添加 StockClearCommand 类,无需修改调用者代码;
  • 可追踪:每个指令有唯一 ID,便于日志记录和问题排查。

四、 设计模式选型核心思路

  1. 先解决问题,再谈模式:不要为了用模式而用模式,简单场景(如查询用户)直接写代码即可;
  2. 遵循设计原则 :所有模式的本质是落地七大设计原则,违背原则的模式使用都是 "过度设计";
  3. 组合使用模式 :实际项目中,模式往往是组合使用的(如工厂模式 + 策略模式代理模式 + 装饰器模式);
  4. 参考框架源码:Spring、MyBatis 等框架是设计模式的最佳实践教材,阅读源码能加深对模式的理解。

五、 总结

设计模式不是 "银弹",而是解决特定问题的工具。在实际项目中,判断是否使用模式的核心标准是:

  • 是否降低了耦合
  • 是否提升了扩展性
  • 是否便于维护和测试

掌握设计模式的关键,不是死记硬背代码结构,而是理解模式背后的设计思想 ------高内聚、低耦合、开闭原则,这样才能在面对复杂业务场景时,灵活选择合适的模式。

相关推荐
阿拉斯攀登2 小时前
设计模式:工厂模式概要
java·设计模式·抽象工厂模式
阿拉斯攀登2 小时前
设计模式:构建者模式-示例二
设计模式·建造者模式
曹轲恒2 小时前
Java Collections & Arrays 工具类
java
.卡2 小时前
(022)FastJson 序列化导致的 java.util.ConcurrentModificationException
java
武子康2 小时前
Java-218 RocketMQ Java API 实战:同步/异步 Producer 与 Pull/Push Consumer
java·大数据·分布式·消息队列·rocketmq·java-rocketmq·mq
Coder_Boy_2 小时前
Spring AI 设计模式综合应用与完整工程实现
人工智能·spring·设计模式
不爱吃米饭_2 小时前
Spring Security、Apache Shiro、Sa-Token,主流安全框架如何选择?
java·安全
我命由我123452 小时前
Java 开发 - 含有 null 值字段的对象排序(自定义 Comparator、使用 Comparator、使用 Stream API)
java·开发语言·学习·java-ee·intellij-idea·学习方法·intellij idea
GISERLiu2 小时前
Spring Boot + Spring Security
java·spring boot·spring