模板方法, 我们平时经常填写的各种表格就是模板,很多重复的文字不用书写,比如我们申请银行卡的时候,需要填写如下模板。
信用卡申请表
客户姓名:XXX
身份证号:XXXXXXXXXXXX
本人同意以下授权,实例省略实例省略实例省略实例
省略实例省略实例省略实例省略实例省略。
申请人签名:XXXX
申请日期:XXXXX
只需要在XXX的地方替换为自己需要的就行,编程里使用的模板思想和这个是完全一样的,也是为了不重复写重复的代码,非常简单不过是XXX变成了抽象方法,具体的时候替换为真实的程序,在java中XXX的语法是抽象方法,替换是通过子类或匿名子类而已,示例如下:
比如我们加载博客文章,为了提升性能,我们可以使用数据库+缓存提升数据的访问速度,你会发现数据库和缓存的结合代码是共用的,不仅仅适用于文章,也适用于电商的商品展示:
XXX:
@Slf4j
public abstract class DataLoader<T> {
public abstract T getObjectFromCache(IdPin idPin);
public abstract T getObjectFromDb(IdPin idPin);
public abstract void setObjectToCache(IdPin idPin, T Object);
public T getObject(IdPin idPin, DataLoaderStrategyEnum dataLoadStrategyEnum) {
T object = null;
//从cache中取
if (DataLoaderStrategyEnum.CACHE.equals(dataLoadStrategyEnum) || DataLoaderStrategyEnum.CACHE_DB.equals(dataLoadStrategyEnum)) {
object = this.getObjectFromCache(idPin);
if (null != object) {
TrackContext.appendTrackInfo(String.format("redisGet blog from Redis success,id %s", idPin.getId()));
return object;
}
}
//从持久化介质取
if (DataLoaderStrategyEnum.CACHE_DB.equals(dataLoadStrategyEnum)) {
//从db取,如果取到放进缓存
object = this.getObjectFromDb(idPin);
TrackContext.appendTrackInfo(String.format("redisGet blog from db success,id %s", idPin.getId()));
//存放Cache
if (null != object) {
this.setObjectToCache(idPin, object);
TrackContext.appendTrackInfo(String.format("redisSet blog to Redis success,id %s", idPin));
}
}
return object;
}
}
具体替换XXX的子类如下:
DataLoader<CplArticle> dataLoader = new DataLoader<CplArticle>() {
@Override
public CplArticle getObjectFromDb(IdPin idPin) {
return articleRepository.getCplArticleById(idPin);
}
@Override
public CplArticle getObjectFromCache(IdPin idPin) {
return articleCache.getCplArticleById(idPin.getId());
}
@Override
public void setObjectToCache(IdPin idPin, CplArticle cplArticle) {
articleCache.cacheCplArticle(idPin.getId(), cplArticle);
}
};
var idPin = IdPin.of(articleId, flyContext.getPin());
var cplArticle = dataLoader.getObject(idPin, strategyEnum);