模板方法
定义: 在模板方法中,有一个公共的抽象类声明了一个模板方法,其中包括:
- 必定会执行的模板方法,子类无法实现
- 用户必须实现的方法,该方法表达不同的行为(abstart)
- 根据自身需求选择实现的钩子方法(Hook)
而对于外部来说,只暴露接口定义的行为。设计原则:对扩展开放,对修改关闭。
用例图
其实我在博客平台发文章这件事,就符合模板方法。
对于用户来说,在博客平台进行文章发布的行为,都要经过几个步骤:
- 新建一个文章
- 写自己的内容
- 将文章进行发布
最后,你可以根据自己的需求,对平台进行充值,享用更高级的平台服务。
在这个过程中,所有的用户都需要使用博客平台进行新建文章和发布文章的操作,但是写作内容因人而异,但是你必须编辑了内容才可以发布文章,而升级VIP则根据用户自己的需求,如果觉得抽象,可以看看我画的用例图。

代码示例
- ArticleEvent
package com.xjm.design.template;
/**
* @author jaymin
* 2020/12/6 1:48
*/
public interface ArticleEvent {
/**
* 发布文章
*/
void pushArticle();
}
- ArticleEventTemplate
package com.xjm.design.template;
/**
* @author jaymin
* 2020/12/6 1:49
*/
public abstract class ArticleEventTemplate implements ArticleEvent {
@Override
public final void pushArticle() {
joinMembership();
createArticle();
write();
push();
}
/**
* 钩子方法,默认当前用户为普通用户
*/
protected void joinMembership() {
System.out.println("************普通用户****************");
}
/**
* 平台默认实现,所有用户复用这个逻辑,不可以重写
*/
private void createArticle() {
System.out.println("新建文章");
}
/**
* 抽象方法,子类必须实现
*/
protected abstract void write();
/**
* 平台默认实现,所有用户复用这个逻辑,不可以重写
*/
private void push() {
System.out.println("发布 \n");
}
}
- NormalUserArticleEvent
package com.xjm.design.template;
/**
* @author jaymin
* 继承模板类,当前角色为普通用户br>
* 2020/12/6 15:07
*/
public class NormalUserArticleEvent extends ArticleEventTemplate {
@Override
public void write() {
System.out.println("随便写写:---------");
}
}
- MarketingUserArticleEvent
package com.xjm.design.template;
/**
* @author jaymin<br>
* 继承模板类,当前角色为营销号<br>
* 2020/12/6 15:09
*/
public class MarketingUserArticleEvent extends ArticleEventTemplate {
@Override
public void write() {
System.out.println("震惊!当代年轻人竟然平均996:---------");
}
@Override
public void joinMembership() {
System.out.println("***********会员用户************");
}
}
package com.xjm.design.template;
/**
* @author jaymin<br>
* 继承模板类,当前角色为营销号<br>
* 2020/12/6 15:09
*/
public class MarketingUserArticleEvent extends ArticleEventTemplate {
@Override
public void write() {
System.out.println("震惊!当代年轻人竟然平均996:---------");
}
@Override
public void joinMembership() {
System.out.println("***********会员用户************");
}
}
- AuthorUserArticleEvent
package com.xjm.design.template;
/**
* @author jaymin<br>
* 继承模板类,当前角色为专业的作家<br>
* 2020/12/6 15:11
*/
public class AuthorUserArticleEvent extends ArticleEventTemplate {
@Override
public void write() {
System.out.println("论中华五千年的文化传承:--------");
}
@Override
public void joinMembership() {
System.out.println("************会员用户***********");
}
}
- TemplatePatternDemo
package com.xjm.design.template;
/**
* @author jaymin
* 2020/12/6 15:14
*/
public class TemplatePatternDemo {
public static void main(String[] args) {
ArticleEvent normalUserArticleEvent = new NormalUserArticleEvent();
ArticleEvent marketingUserArticleEvent = new MarketingUserArticleEvent();
ArticleEvent authorUserArticleEvent = new AuthorUserArticleEvent();
normalUserArticleEvent.pushArticle();
marketingUserArticleEvent.pushArticle();
authorUserArticleEvent.pushArticle();
}
}
- 输出结果

总结
- 模板方法将代码复用这件事落实地很好,将可复用的代码在模板类中进行实现,将钩子与必须实现的方法,交由子类实现。
- 模板方法最好加上final,防止子类重写。
- 缺点:不同的实现都需要创建一个类进行实现,会导致类膨胀。
- 学习Spring源码的过程中,可以看看refresh(),它就是一个模板方法的体现,还有Spring data 中的很多类,诸如:jdbcTemplate、jmsTemplate等等
网友评论