摘要:学习的过程是由已知概念去学习未知概念,编程中的很多概念,并不是新的概念,平时生活中都有使用。我们通过生活中的经验和编程类似概念类比思考,来加速我们的学习过程。
本文讨论GOF中最常用的设计模式「模板方法-TemplateMethod」,这个模式不仅仅编程中常用,生活中也是经常会使用的,比如当你申请银行卡或信用卡的时候,就会用到「模板方法」。
模板方法GOF:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。
1. 生活中申请信用卡表格
比如我们申请银行卡的时候,需要填写如下表格,每个人只需要在XXX的地方填写为自己的信息就可以了。
信用卡申请表 客户姓名:XXX 身份证号:XXXXXXXXXXXX 本人同意以下授权,实例省略实例省略实例省略实例 省略实例省略实例省略实例省略实例省略。 申请人签名:XXXX 申请日期:XXXXX
如果没有这个「文档模板」,我们每个人都重复书写全部的这个申请表,显然是重复的,客户大概率就换家银行办卡了。
「文档模板」其实是每个人申请信用卡的重复文字部分,模板打印出来,每个人只需要申请的时候填写空白部分就可以了。
模板的处理办法,就是共用重复的部分做成模板,每个场景只需要关注变化部分。 下面我们可以看看编程中的「模板方法」模式是否是一样的。
2. 编程中使用模板方法
编程里使用的模板思想和申请银行卡用的模板是完全一样的,目的是为了不重复书写代码。
- 填空形式从银行卡申请表变成了抽象类。
- 申请表的空白填空变成了抽象方法。
- 填空的过程替换为子类程序继承父类进行实现抽象方法或OverWrite。
3. 代码实例
比如我们互联网架构中,为了提升性能,我们可以使用数据库+缓存提升数据的访问速度。数据库和缓存的数据配合过程在每个模块都是一样的(比如既可用于文章缓存,也可用于缓存用户信息),没必要重复书写。 模板部分:统一定义了算法过程框架(DB和缓存的结合使用过程)
``` public abstract class DataLoader { public abstract T getObjectFromCache(Long id);
public abstract T getObjectFromDb(Long id);
public abstract void setObjectToCache(Long id, T Object);
public T getObject(Long id) {
//先从cache中取
T object = this.getObjectFromCache(id);
if (null != object) {
//缓存中渠道直接返回
return object;
}
//缓存中取不到,再从db取
object = this.getObjectFromDb(id);
//把DB取到的结果放进缓存,此处只是示例,真实线上需要对null进行占位,不然会不存在数据一直击穿到数据库
if (null != object) {
this.setObjectToCache(id, object);
}
return object;
}
} ``` 具体填空的子类如下:只需要填空,不需要考虑了解整个过程细节
``` //dao和cache不应该耦合mysql和redis,此处这样命名为了简化本示例,增加易读性。 DataLoader
@Override
public Article getObjectFromCache(Long id) {
//从缓存根据ID查询文章
return articleCacheRedis.getCplArticleById(id);
}
@Override
public void setObjectToCache(Long id, Article article) {
//保存文章到Redis缓存中
articleCacheRedis.cacheArticle(id, article);
}
}; Long id = 100L; Article article = dataLoader.getObject(id); ```