概述
装饰器模式:在原有结构,动态地为对象添加职责,它是一种灵活的扩展功能方式。
业务场景:创建订单
假设你正在开发一个电商系统,用户在创建订单时可以选择不同的服务(如折扣、配送、礼品包装等)。你需要灵活地计算订单的总价,并能够动态地添加或移除这些服务。
核心思想
在创建订单场景中的核心思想是动态扩展,它通过组合而非继承的方式,创建时能不断扩展,订单对象传进入参不断扩展。
1. 基础组件接口 (Order
)
public interface Order { double getTotalPrice(); // 获取订单总价 String getDescription(); // 获取订单描述 }
2. 具体组件 (BasicOrder
)
public class BasicOrder implements Order { private double basePrice; // 订单基础价格 public BasicOrder(double basePrice) { this.basePrice = basePrice; } @Override public double getTotalPrice() { return basePrice; // 返回基础价格 } @Override public String getDescription() { return "基础订单(价格:" + basePrice + ")"; } }
3. 装饰器基类 (OrderDecorator
)
public abstract class OrderDecorator implements Order { protected Order decoratedOrder; public OrderDecorator(Order order) { this.decoratedOrder = order; } @Override public double getTotalPrice() { return decoratedOrder.getTotalPrice(); } @Override public String getDescription() { return decoratedOrder.getDescription(); } }
4. 具体装饰器
折扣装饰器 DiscountDecorator
public class DiscountDecorator extends OrderDecorator { private double discountRate; // 折扣率 public DiscountDecorator(Order order, double discountRate) { super(order); this.discountRate = discountRate; } @Override public double getTotalPrice() { return super.getTotalPrice() * (1 - discountRate); // 应用折扣 } @Override public String getDescription() { return super.getDescription() + " + 折扣(" + (discountRate * 100) + "%)"; } }
加急配送装饰器 ExpressShippingDecorator
public class ExpressShippingDecorator extends OrderDecorator { private double expressShippingFee; // 加急配送费用 public ExpressShippingDecorator(Order order, double expressShippingFee) { super(order); this.expressShippingFee = expressShippingFee; } @Override public double getTotalPrice() { return super.getTotalPrice() + expressShippingFee; // 添加加急配送费用 } @Override public String getDescription() { return super.getDescription() + " + 加急配送(费用:" + expressShippingFee + ")"; } }
礼品包装装饰器 GiftWrapDecorator
public class GiftWrapDecorator extends OrderDecorator { private double giftWrapFee; // 礼品包装费用 public GiftWrapDecorator(Order order, double giftWrapFee) { super(order); this.giftWrapFee = giftWrapFee; } @Override public double getTotalPrice() { return super.getTotalPrice() + giftWrapFee; // 添加礼品包装费用 } @Override public String getDescription() { return super.getDescription() + " + 礼品包装(费用:" + giftWrapFee + ")"; } }
5. 客户端代码
public class OrderSystem { public static void main(String[] args) { // 创建一个基础订单 Order order = new BasicOrder(100.0); System.out.println(order.getDescription()); System.out.println("总价: " + order.getTotalPrice()); // 添加折扣 order = new DiscountDecorator(order, 0.1); // 10% 折扣 System.out.println(order.getDescription()); System.out.println("总价: " + order.getTotalPrice()); // 添加加急配送 order = new ExpressShippingDecorator(order, 15.0); // 加急配送费用 15 System.out.println(order.getDescription()); System.out.println("总价: " + order.getTotalPrice()); // 添加礼品包装 order = new GiftWrapDecorator(order, 5.0); // 礼品包装费用 5 System.out.println(order.getDescription()); System.out.println("总价: " + order.getTotalPrice()); } }
6. 输出
基础订单(价格:100.0) 总价: 100.0 基础订单(价格:100.0) + 折扣(10.0%) 总价: 90.0 基础订单(价格:100.0) + 折扣(10.0%) + 加急配送(费用:15.0) 总价: 105.0 基础订单(价格:100.0) + 折扣(10.0%) + 加急配送(费用:15.0) + 礼品包装(费用:5.0) 总价: 110.0
业务场景总结
-
问题:订单可能需要添加多种附加服务(如折扣、运费、包装费等),如果为每种组合创建单独的类,会导致类爆炸。
-
解决方案:使用装饰器模式,动态地为订单添加附加服务。
-
优点:
-
灵活扩展功能,无需修改订单类的核心逻辑。
-
支持动态添加或移除服务,符合开闭原则。
-
避免类爆炸,组合功能更加简洁。
-
其他业务场景
-
购物车:为购物车动态添加优惠券、满减活动等。
-
订阅服务:为用户订阅动态添加附加功能(如高级功能、额外存储等)。
-
账单系统:为账单动态添加税费、服务费等。
装饰器模式在创建订单场景中的核心思想是动态扩展,它通过组合而非继承的方式,灵活地为订单添加功能或服务。