设计模式-装饰器模式

设计模式-装饰器模式写在前面 Hello 我是易元 这篇文章是我学习设计模式时的笔记和心得体会 如果其中有错误 欢迎大家留言指正 代码初期的快速实现场景 互联网初创公司 极客海淘 团队只有 3 个成员 小易 产品小美 测试大哥老李 迎来了系统

大家好,欢迎来到IT知识分享网。

写在前面

Hello,我是易元,这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误,欢迎大家留言指正!

代码初期的快速实现

场景:互联网初创公司”极客海淘”,团队只有3个成员(小易、产品小美、测试大哥老李),迎来了系统的第一次需求扩张(折扣),老板大手一挥:”先用起来再说!”

/ * 订单逻辑处理器 */ public class OrderProcessor { public double process(Double amount) { System.out.println("计算订单金额:" + amount); return amount; } } / * 订单折扣处理器 */ public class DiscountOrderProcessor extends OrderProcessor { private Double discount; public DiscountOrderProcessor(Double discount) { this.discount = discount; } public double process(Double amount) { double process = super.process(amount); System.out.println("订单折扣:" + discount); System.out.println("商品折扣金额:" + (process * discount)); return amount - process * discount; } } 

团队日常
小易(叉腰):”搞定!”

紧急功能的应对方案

团队日常
产品小美(眨眼):”易哥,还能加个进口关税功能吗?客户提出的需求,而且催得紧~”
老李(摸鱼):”别慌,反正现在代码简单~”

订单关税处理器

public class TariffOrderProcessor extends OrderProcessor { private Double tariff; public TariffOrderProcessor(Double tariff) { this.tariff = tariff; } public double process(Double amount) { System.out.println("商品关税:" + tariff); System.out.println("商品关税金额:" + amount * tariff); return super.process(amount * tariff + amount); } } 

订单关税 折扣 处理器

public class TariffDiscountOrderProcessor extends DiscountOrderProcessor { private Double tariff; public TariffDiscountOrderProcessor(Double tariff, Double discount) { super(discount); this.tariff = tariff; } public double process(Double amount) { System.out.println("商品关税比例:" + tariff); System.out.println("商品关税金额:" + (amount * tariff)); return super.process(amount + amount * tariff); } } 

设计缺陷显形

团队日常
产品小美(递咖啡):”易哥辛苦了,能再加赠品功能吗?客户说下次一定…”
小易(抓头发):”这继承树是要捅破天花板啊!”
老李(拍桌子):”测试用例要写疯了!这代码没法维护!”

累加功能存在的隐患

问题清单

  1. 类爆炸:每加一个功能就继承一个子类,现在代码库里有TariffDiscountOrderProcessor、OrderProcessor、DiscountOrderProcessor…
  2. 功能耦合:进口订单和赠品功能写死在一起,无法单独存在
  3. 维护地狱:改个税率要改10个类!

引入设计模式重构

场景:小易为了不被人说是屎山,偷偷学习了《设计模式之美》,决心用装饰器模式拯救订单系统。
设计模式选择:装饰器模式(Decorator Pattern)
核心目标:优雅扩展,让产品经理的嘴不再开过山车

装饰器模式四要素

角色 职责 订单系统示例 Component 定义基础操作的接口 OrderDecorator ConcreteComponent 基础实现类 OrderProcessorImpl Decorator 持有组件引用并实现相同接口 OrderDecorator ConcreteDecorator 添加具体功能的装饰器 DiscountDecorator

重构:装饰器模式实践

步骤1:定义组件接口(订单处理基类)

public abstract class OrderDecorator implements OrderProcessor { protected final OrderProcessor processor; protected OrderDecorator(OrderProcessor processor) { this.processor = processor; } @Override public abstract double process(Double amount); } 

步骤2:实现基础组件(裸奔版处理器)

public class OrderProcessorImpl implements OrderProcessor { @Override public double process(Double amount) { System.out.println("------------------订单基础处理------------------"); System.out.println("计算订单金额:" + amount); System.out.println("订单基础逻辑处理......."); System.out.println("------------------------------------------------"); return amount; } } 

步骤3:创建装饰器基类(功能扩展骨架)

public abstract class OrderDecorator implements OrderProcessor { protected final OrderProcessor processor; protected OrderDecorator(OrderProcessor processor) { this.processor = processor; } @Override public abstract double process(Double amount); } 

步骤4:实现具体装饰器(功能插件)

// 订单打折处理器类(具体装饰器) public class DiscountDecorator extends OrderDecorator { private final Double discount; protected DiscountDecorator(OrderProcessor processor, Double discount) { super(processor); this.discount = discount; } @Override public double process(Double amount) { System.out.println("------------------订单打折处理------------------"); System.out.println("商品订单金额:" + amount); System.out.println("订单折扣:" + discount); System.out.println("商品折扣金额:" + (amount * discount)); System.out.println("------------------------------------------------"); return super.processor.process(amount * (1 - discount)); } } // 订单关税处理器类(具体装饰器) public class TariffDiscountDecorator extends OrderDecorator { private final Double tariff; protected TariffDiscountDecorator(OrderProcessor processor, Double tariff) { super(processor); this.tariff = tariff; } @Override public double process(Double amount) { System.out.println("------------------订单关税处理------------------"); System.out.println("商品订单金额:" + amount); System.out.println("商品关税比例:" + tariff); System.out.println("商品关税金额:" + (amount * tariff)); System.out.println("------------------------------------------------"); return super.processor.process(amount * (1 + tariff)); } } 

测试代码

public class OrderProcessorTest { @Test public void discountTest() { OrderProcessor orderDecorator = new OrderProcessorImpl(); // 促销增加 10% 折扣 orderDecorator = new DiscountDecorator(orderDecorator, 0.1); // 增加关税 orderDecorator = new TariffDiscountDecorator(orderDecorator, 0.3); double process = orderDecorator.process(400D); System.out.println("订单实际金额:" + process); } } 

重构后效果

系统改进点

  • 动态组合:运行时任意组合功能
  • 正交扩展:新增装饰器不影响现有逻辑
  • 类型安全:所有装饰器实现统一接口
  • 顺序敏感:装饰顺序影响最终结果(符合业务特性)

复杂度对比

指标 重构前 重构后 类数量 O(2ⁿ) O(n) 新增功能成本 修改现有类 新增装饰器类 测试覆盖率 60% 95%

赠品需求实现

public class GiftDecorator extends OrderDecorator { private final String giftName; protected GiftDecorator(OrderProcessor processor, String giftName) { super(processor); this.giftName = giftName; } @Override public double process(Double amount) { System.out.println("------------------订单赠品处理------------------"); System.out.println("商品订单金额:" + amount); System.out.println("商品赠品名称:" + giftName); System.out.println("-----------------------------------------------"); return super.processor.process(amount); } } 

测试代码

public class OrderProcessorTest { @Test public void discountTest() { OrderProcessor orderDecorator = new OrderProcessorImpl(); orderDecorator = new GiftDecorator(orderDecorator, "灰太狼玩偶"); orderDecorator = new DiscountDecorator(orderDecorator, 0.1); orderDecorator = new TariffDiscountDecorator(orderDecorator, 0.3); double process = orderDecorator.process(400D); System.out.println("订单实际金额:" + process); } } 

团队新日常

长话短说

核心思想:通过组合实现功能的动态叠加,保持类职责单一性(想加功能就加层装饰,拆开来看每个装饰器只管一件事)

何时选择装饰器模式?

  • 需要动态、透明地扩展对象功能
  • 不宜使用子类扩展(避免类爆炸)
  • 需要运行时组合不同功能

何时避免使用?

  • 扩展功能需要完全改变接口
  • 装饰顺序不影响结果时(可能过度设计)
  • 性能敏感的底层操作(装饰器可能引入开销)

适用场景特征

  1. 需要动态、透明地添加职责
  2. 不能使用继承或需要避免子类膨胀
  3. 需要撤销或替换已添加的功能

代码编写步骤

  1. 定义组件接口(OrderComponent)
  2. 创建基础实现类(BasicOrder)
  3. 创建装饰器基类(OrderDecorator)
  4. 实现具体装饰器(ImportTaxDecorator)
  5. 客户端按需组合装饰器

示例代码结构

public interface Component { ... } // 组件接口 public class ConcreteComponent implements Component { ... } // 基础实现类 public abstract class Decorator implements Component { ... } // 装饰器基类 public class ConcreteDecoratorA extends Decorator { ... } // 具体装饰器 A public class ConcreteDecoratorB extends Decorator { ... } // 具体装饰器 B 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/178757.html

(0)
上一篇 2025-05-16 09:10
下一篇 2025-05-16 09:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信