一 . 装饰器模式简单的介绍
装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外,装饰器模式还有一个特点,那就是可以对原始类嵌套使用多个装饰器。为了满足这个应用场景,在设计的时候,装饰器类需要跟原始类继承相同的抽象类或者接口。
JDK中I/O相关的接口就是基于这种设计模式实现的。需要注意的是I/O中通过FilterInputStream类来实现了InputStream 所有的默认方法,这样其他装饰器类只用实现其需要增强的方法即可,无需简单包裹对 InputStream 对象的函数调用。
例如:首先定义了I/O的基础类 InputStream, 然后FilterInputStream继承了InputStream,然后将InputStream的方法都进行了默认实现,然后BufferedInputStream、DataInputStream都继承FilterInputStream这个装饰器父类。
二 .优化复杂的商品价格的计算
1. 需求背景
购买商品时经常会用到的限时折扣、红包、抵扣券以及特殊抵扣金等。
例如,每逢双十一,为了加大商城的优惠力度,开发往往要设计红包 + 限时折扣或红包 + 抵扣券等组合来实现多重优惠。而在平时,由于某些特殊原因,商家还会赠送特殊抵扣券给购买用户,而特殊抵扣券 + 各种优惠又是另一种组合方式。
要实现以上这类组合优惠的功能,最快、最普遍的实现方式就是通过大量 if-else 的方式来实现。但这种方式包含了大量的逻辑判断,致使其他开发人员很难读懂业务, 并且一旦有新的优惠策略或者价格组合策略出现,就需要修改代码逻辑,代码扩展性不强,不能满足开闭原则。
2. 实现
下面使用装饰器模式来实现复杂的价格组合,可以灵活的实现各种价格策略的组合。
完整代码git下载地址:装饰器demo
首先我们看下示例的类的结构。
其中Order为订单和Merchandise商品的属性类,主订单包含若干详细订单,详细订单中记录了商品信息,商品信息中包含了促销类型信息,一个商品可以包含多个促销类型。
/**
* 主订单
* @author tr.wang
*
*/
public class Order {
private int id; //订单ID
private String orderNo; //订单号
private BigDecimal totalPayMoney; //总支付金额
private List<OrderDetail> list; //详细订单列表
}
/**
* 详细订单
* @author tr.wang
*
*/
public class OrderDetail {
private int id; //详细订单ID
private int orderId;//主订单ID
private Merchandise merchandise; //商品详情
private BigDecimal payMoney; //支付单价
}
/**
* 商品
* @author tr.wang
*
*/
public class Merchandise {
private String sku;//商品SKU
private String name; //商品名称
private BigDecimal price; //商品单价
private List<SupportPromotions> supportPromotionsList; //支持促销类型
}
/**
* 促销类型
* @author tr.wang
*
*/
public class SupportPromotions implements Cloneable{
private int id;//该商品促销