设计模式|装饰器模式-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类结构图如下:
文章图片
其基本的实现,就是基于HashMap实现的缓存,实现类为PerpetualCache,代码如下:
public class PerpetualCache implements Cache {private final String id;
private Map
FifoCache实现装饰模式为例,以Deque双向链表实现缓存的先进先出测试,定义Cache delegate委托属性,源码如图:
public class FifoCache implements Cache {/**
* 委托的缓存接口
*/
private final Cache delegate;
private final Deque
计价功能的装饰器实现 在实际开发中,以计价功能为例,在根据价格列表计算出基础的支付价格,业务场景中,会添加根据拥有的优惠券,积分,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【设计模式|装饰器模式-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);
}
}
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- 人生感悟记#环境仪器宋庆国成长记#072
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 视频转换器哪种好用()
- NeuVector 会是下一个爆款云原生安全神器吗()
- 操作系统|[译]从内部了解现代浏览器(1)
- 探索免费开源服务器tomcat的魅力
- 机器学习|机器学习 Andrew Ng《Machine Learning》课程笔记1
- 《机器学习实战》高清中文版PDF英文版PDF+源代码下载
- 机器学习一些简单笔记