Skip to content

设计模式实战

字数: 0 字 时长: 0 分钟

设计模式选型

模式名称核心思想典型应用场景
单例全局唯一实例,统一访问入口数据库连接池、线程池、配置管理
工厂方法由子类决定创建哪种对象可扩展的对象类型
抽象工厂创建产品族一套产品族适应不同场景(如一套 UI 组件适应不同端)
建造者分布构造复杂对象创建包含多部件的复杂对象,比如组装电脑
原型通过克隆现有对象创建新对象减少大量重复对象创建开销,如粒子特效
结构型模式------
适配器转换接口使不兼容的类协同工作集成第三方库(如老接口适配新系统)
代理控制对其他对象的访问延迟加载、权限控制、日志记录
装饰器组合替代继承,动态添加新功能日志增强、权限校验、性能监控
外观为复杂子系统提供统一的对外接口数据库操作封装、复杂的第三方服务集成
桥接解耦抽象与实现,支持独立扩展多渠道消息推送系统、支付系统、广告系统
组合以树形结构统一处理单个对象和对象组合文件系统、UI 组件嵌套
享元共享对象,节省内存,提高性能网页图标缓存、文字编辑器种的字符缓存
行为型模式------
观察者一对多依赖关系,状态变更自动通知社交媒体订阅通知、电商订单状态变化通知
策略封装算法族,支持运行时切换支付方式选择、折扣计算策略
命令请求封装为对象,支持撤销/重做任务调度系统、界面操作的撤销与重做
中介者通过中介对象管理对象间通信聊天室
备忘录保存/恢复对象内部状态文档编辑器撤销/重做功能、游戏存档功能
模板方法定义算法骨架,子类重写特定步骤订单处理流程标准化、框架通用设计
迭代器提供统一遍历集合的方法屏蔽不同集合结构的遍历,统一接口
状态对象行为随状态改变而改变工作流引擎
责任链请求沿处理器链传递,直到被处理审批流程、异常处理链
解释器为特定语法定义解释器编译器、规则引擎
访问者解耦数据结构与操作文档系统格式转换

如何使用设计模式?

架构设计的难度所在,实际业务场景往往是多种因素混合在一起的复杂场景,使用单一设计模式难以实现,往往需要多种设计模式互相合作完成

订单系统案例

不同订单有不同的折扣策略(比如满减、打折、VIP折上折),我们可以组合四种设计模式来设计:

  • 使用策略模式封装各种折扣逻辑
  • 使用工厂方法模式来创建对应的折扣策略实例
  • 使用装饰器模式对策略功能进行增强,增加日志、权限控制等附加功能
  • 使用责任链模式来顺序叠加处理多个优惠
java
import java.util.List;

// 1. 定义折扣策略接口
interface DiscountStrategy {
    double calculate(double originalPrice);
}

// 2. 定义具体策略实现类
class FullReductionStrategy implements DiscountStrategy {
    @Override
    public double calculate(double originalPrice) {
        return originalPrice >= 100 ? originalPrice - 10 : originalPrice;
    }
}

class PercentageStrategy implements DiscountStrategy {
    @Override
    public double calculate(double originalPrice) {
        return originalPrice * 0.8; // 8折
    }
}

class VipDiscountStrategy implements DiscountStrategy {
    @Override
    public double calculate(double originalPrice) {
        return originalPrice * 0.88; // VIP 折上折
    }
}

// 3. 定义一个日志装饰器记录策略前后价格
class LogDecorator implements DiscountStrategy {
    private final DiscountStrategy strategy;

    public LogDecorator(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    @Override
    public double calculate(double originalPrice) {
        System.out.println("策略前价格:" + originalPrice);
        double result = strategy.calculate(originalPrice);
        System.out.println("策略后价格:" + result);
        return result;
    }
}

// 4. 定义责任链接口
abstract class DiscountHandler {
    protected DiscountHandler next;

    public void setNext(DiscountHandler next) {
        this.next = next;
    }

    public double apply(double originalPrice) {
        double result = handle(originalPrice);
        if (next != null) {
            return next.apply(result);
        }
        return result;
    }

    protected abstract double handle(double price);
}

// 5. 实现具体责任链节点,包装每个策略
class StrategyHandler extends DiscountHandler {
    private final DiscountStrategy strategy;

    public StrategyHandler(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    @Override
    protected double handle(double price) {
        return strategy.calculate(price);
    }
}

// 6. 策略工厂集中创建策略实例
class DiscountStrategyFactory {
    public static DiscountStrategy createStrategy(String type) {
        switch (type) {
            case "full" -> new FullReductionStrategy();
            case "percentage" -> new PercentageStrategy();
            case "vip" -> new VipDiscountStrategy();
            default -> throw new IllegalArgumentException("未知折扣类型");
        }
    }
}

// 7. 订单处理类 整合责任链 + 策略 + 装饰器 + 工厂
class OrderService {
    public void handleOrder(double originalPrice, List<String> discountType) {
        // 构建责任链
        DiscountHandler head = null;
        DiscountHandler current = null;
        
        for (String type : discountType) {
            // 策略工厂根据类型创建实例
            DiscountStrategy strategy = DiscountStrategyFactory.createStrategy(type);
            // 使用装饰器增强实例
            DiscountStrategy enhancedStrategy = new LogDecorator(strategy);
            // 封装为责任链节点
            DiscountHandler handler = new StrategyHandler(enhancedStrategy);
            
            if (head == null) {
                head = handler;
                current = handler;
            } else {
                current.setNext(handler);
                current = handler;
            }
        }
        System.out.println("打折前价格: " + originalPrice);
        double result = head != null ? head.apply(originalPrice) : originalPrice;
        System.out.println("最终支付金额:" + result);
    }
}