资讯动态

设计模式实战解析:创建型、结构型与行为型模式应用

发布时间:2026/10/29 22:40:21 来源:尧图企业网站定制
1. 设计模式概述为什么我们需要它们2004年我第一次接手一个遗留系统时面对5万行意大利面条式的代码彻底懵了。那是我第一次深刻理解设计模式的价值——它们不是学术象牙塔里的概念而是解决真实工程问题的利器。设计模式本质上是前辈工程师们总结的最佳实践配方就像烹饪中的经典菜谱告诉我们如何把代码组织得更优雅、更易维护。在面向对象编程中设计模式主要解决三类问题创建问题对象该由谁创建如何创建工厂模式、单例模式结构问题对象之间如何组合适配器模式、装饰器模式行为问题对象间如何通信观察者模式、策略模式注意设计模式不是银弹滥用模式比不用更危险。我曾见过一个简单CRUD接口被套上7种模式维护成本反而暴增。2. 创建型模式实战解析2.1 单例模式的正确打开方式去年我们电商系统因为不当的单例实现导致促销期间库存计算错误损失惨重。以下是血泪教训总结出的最佳实践public class OrderService { private static volatile OrderService instance; private OrderService() {} // 关键点1私有构造 public static OrderService getInstance() { if (instance null) { // 第一次检查 synchronized (OrderService.class) { if (instance null) { // 第二次检查 instance new OrderService(); } } } return instance; } }关键细节volatile防止指令重排序JVM层面优化可能导致未初始化完成就被使用双重检查锁定DCL解决性能问题私有构造器防止反射攻击2.2 工厂方法 vs 抽象工厂我们物流系统曾因选错工厂模式导致扩展困难维度工厂方法抽象工厂适用场景单一产品族多个相关产品族扩展性新增产品容易新增产品族容易典型应用JDBC的DriverManagerGUI跨平台组件库实际案例当需要支持新的快递公司时用工厂方法当需要同时处理运单、面单、轨迹查询时用抽象工厂。3. 结构型模式深度应用3.1 适配器模式老旧系统改造利器我们银行系统对接第三方支付时就用适配器模式解决了接口不兼容问题// 第三方支付接口 interface ThirdPartyPayment { void pay(String orderId, BigDecimal amount); } // 我们系统的接口 interface BankPayment { void processPayment(PaymentRequest request); } // 适配器实现 class PaymentAdapter implements BankPayment { private ThirdPartyPayment thirdParty; public void processPayment(PaymentRequest request) { thirdParty.pay(request.getId(), request.getAmount()); } }关键技巧适配器模式特别适合处理遗留系统改造但要注意不要形成适配器链多个适配器嵌套这通常是架构问题的信号。3.2 装饰器模式Java I/O的经典实现Java的IO流就是装饰器模式的教科书案例// 基础组件 InputStream fileStream new FileInputStream(data.txt); // 装饰器叠加 InputStream buffered new BufferedInputStream(fileStream); InputStream gzip new GZIPInputStream(buffered);这种设计允许动态添加功能如缓冲、压缩比继承更灵活。我在处理大文件导出时通过装饰器组合将内存占用从2GB降到了50MB。4. 行为型模式最佳实践4.1 观察者模式订单状态通知实战我们的订单系统使用改良版观察者模式处理30种状态变更通知// 事件总线简化版实现 public class EventBus { private MapClass?, ListConsumer? handlers new ConcurrentHashMap(); public T void subscribe(ClassT eventType, ConsumerT handler) { handlers.computeIfAbsent(eventType, k - new CopyOnWriteArrayList()) .add(handler); } public void publish(Object event) { ListConsumer? consumers handlers.get(event.getClass()); if (consumers ! null) { consumers.forEach(c - ((ConsumerObject)c).accept(event)); } } } // 使用示例 eventBus.subscribe(OrderPaidEvent.class, event - { // 发短信通知 smsService.send(event.getOrder()); });性能优化点使用CopyOnWriteArrayList避免并发修改异常事件类型预分类提升查找效率引入异步处理避免阻塞主流程4.2 策略模式支付渠道选择算法在跨境支付场景中我们根据汇率、手续费、到账时间动态选择最优支付渠道public interface PaymentStrategy { PaymentResult execute(PaymentRequest request); } public class PaymentSelector { private ListPaymentStrategy strategies; public PaymentResult selectBest(PaymentRequest request) { return strategies.stream() .map(s - s.execute(request)) .min(Comparator.comparing(PaymentResult::getTotalCost)) .orElseThrow(); } }实际业务中我们会给每个策略设置权重考虑成功率、风控等级等因素形成多维度的决策矩阵。5. 模式混用与反模式警示5.1 MVC中的模式组合一个健康的Spring MVC应用通常包含前端控制器模式DispatcherServlet策略模式HandlerAdapter工厂方法ViewResolver模板方法AbstractController但我在代码审查时经常发现这些问题在Controller中使用单例导致线程安全问题Service层过度使用装饰器使调用链难以追踪滥用观察者模式导致事件风暴event storming5.2 设计模式代码异味这些情况可能意味着模式被误用类的名字包含Manager、Util却实现着策略模式需要查看5个以上类才能理解基本逻辑新增需求总是需要修改现有模式结构单元测试需要大量mock才能运行我曾重构过一个模式博物馆项目将23种设计模式全部用在了2000行代码里最终用3个简单类替代了原来的15个类性能提升了8倍。6. 现代编程中的模式演进随着函数式编程兴起一些传统模式有了新实现方式6.1 Java Stream中的模式// 原本需要策略模式的地方 orders.stream() .filter(Order::isValid) .sorted(Comparator.comparing(Order::getAmount)) .forEach(this::process);这里融合了策略模式排序比较器责任链模式流式操作观察者模式终端操作触发6.2 Spring Reactor中的响应式模式public MonoOrder getOrderWithFallback(String id) { return primaryService.getOrder(id) .onErrorResume(e - fallbackService.getOrder(id)); }这实际上是装饰器模式添加回退逻辑策略模式错误处理策略观察者模式订阅触发执行在微服务架构下模式应用有了新变化。比如API网关通常结合代理模式路由转发装饰器模式添加鉴权/限流责任链模式过滤器链

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑