装饰器模式(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类结构图如下:
其基本的实现,就是基于HashMap实现的缓存,实现类为PerpetualCache,代码如下:
public class PerpetualCache implements Cache {
private final String id;
private Map<Object, Object> 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<Object> 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会员的计价实现类。
计价类结构图如下:
根据价格计算价格的实现类为DefaultPriceCalculator,代码如下:
public class DefaultPriceCalculator implements PriceCalculation {
/**
* 需要计算的价格列表
*/
private final List<PriceBo> priceList;
public DefaultPriceCalculator(List<PriceBo> 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<CouponBo> coupons;
/**
* 委托的计价器
*/
private final PriceCalculation delegate;
public PriceWithCouponCalculator(CouponFilterPipeline couponFilterPipeline, List<CouponBo> 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);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13641.html