设计模式|装饰器模式-Mybatis教你如何玩

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。简单说就是对同一接口添加新功能时,需要新增一个类,被改造的接口定义为delete(委托)。
mybatis cache装饰器模式的实现 源码学习中,以mybatis中的二级缓存Cache为推荐。在定义缓存Cache接口,实现各类缓存操作。Cache源码如下:

public interface Cache {String getId(); void putObject(Object key, Object value); Object getObject(Object key); Object removeObject(Object key); void clear(); int getSize(); ReadWriteLock getReadWriteLock(); }

PerpetualCache,基于HashMap实现了内存的缓存操作。 LruCache,基于LRU策略删除缓存的实现类。 FifoCache,缓存基于FIFO先进先出的策略获取缓存的实现类。 LoggingCache,为日志统一添加日志的实现类。

cache类结构图如下:
设计模式|装饰器模式-Mybatis教你如何玩
文章图片

其基本的实现,就是基于HashMap实现的缓存,实现类为PerpetualCache,代码如下:
public class PerpetualCache implements Cache {private final String id; private Map cache = new HashMap<>(); public PerpetualCache(String id) { this.id = id; } ...... }

FifoCache实现装饰模式为例,以Deque双向链表实现缓存的先进先出测试,定义Cache delegate委托属性,源码如图:
public class FifoCache implements Cache {/** * 委托的缓存接口 */ private final Cache delegate; private final Deque keyList; private int size; public FifoCache(Cache delegate) { this.delegate = delegate; this.keyList = new LinkedList<>(); this.size = 1024; }......}

计价功能的装饰器实现 在实际开发中,以计价功能为例,在根据价格列表计算出基础的支付价格,业务场景中,会添加根据拥有的优惠券,积分,vip会员身份优惠部分价格。定义计价接口PriceCalculation计算价格,接口代码如下:
public interface PriceCalculation {/** * 价格计算 * * @param orderPriceDto 计价订单dto * @return */ CalculatedPrice calculate(OrderPriceDto orderPriceDto); }


DefaultPriceCalculator,根据价格列表计算价格。 PriceWithCouponCalculator,使用优惠的计价实现类。 PriceWithScoreCalculator,使用积分的计价实现类。 PriceWithVipCalculator,使用vip会员的计价实现类。

计价类结构图如下:
设计模式|装饰器模式-Mybatis教你如何玩
文章图片

根据价格计算价格的实现类为DefaultPriceCalculator,代码如下:
public class DefaultPriceCalculator implements PriceCalculation {/** * 需要计算的价格列表 */ private final List【设计模式|装饰器模式-Mybatis教你如何玩】 priceList; public DefaultPriceCalculator(List priceList) { this.priceList = priceList; }@Override public CalculatedPrice calculate(OrderPriceDto orderPriceDto) {...... } }

使用装饰器模式的价格,例如,使用优惠的计价实现类PriceWithCouponCalculator为例。包含使用的优惠券列表coupons,委托的计价接口PriceCalculation delegate,代码如下:
public class PriceWithCouponCalculator implements PriceCalculation {/** * 优惠券过滤Pipeline */ private final CouponFilterPipeline couponFilterPipeline; /** * 使用的优惠券 */ private final List coupons; /** * 委托的计价器 */ private final PriceCalculation delegate; public PriceWithCouponCalculator(CouponFilterPipeline couponFilterPipeline, List coupons, PriceCalculation delegate) { this.couponFilterPipeline = couponFilterPipeline; this.coupons = coupons; this.delegate = delegate; }@Override public CalculatedPrice calculate(OrderPriceDto orderPriceDto) {// TODO 验证参数couponBo,delegate 必须校验// 原始的计算价格 CalculatedPrice originalCalculatedPrice = delegate.calculate(orderPriceDto); return doCalculateWithCoupon(originalCalculatedPrice, matchedCoupons); } }


    推荐阅读