毕业没多久在东莞的一家制造业企业找了份工作,刚进去是在人力资源部干活,每天给新进来的员工培训,为期三天。培训企业文化、公司规章制度、生产安全、静电放电等。当时是储干(储着被干),而且有好多个,顶头上司是一个培训专员。他喜欢每周四让我们给他写一篇周报,每个人对此都深恶痛绝,又不得不写。当时有个同事,不知道该写什么,怎么写。我就在边上忽悠他,按照四个幼稚地步骤去写:1、发生了什么;2、为什么会发生;3、怎么解决的;4、心得体会。
一、例子
下面用代码去实现每周四写周报的任务,为了偷懒每次都是按照那四个固定套路去写(1、发生了什么;2、为什么会发生;3、怎么解决的;4、心得体会。)。首先写好一个类把这四个套路定义好,每次要写周报,四个套路一套,周报就出来了。
public abstract class AbstractWeeklyReport {
//发生了什么
protected abstract void whatHappen();
//为什么会发生
protected abstract void whyHappen();
//怎么解决的
protected abstract void howSolve();
//学到了什么
protected abstract void haveLearnt();
//生成一篇周报的模板方法
public final void getWeeklyReport(){
whatHappen();
whyHappen();
howSolve();
haveLearnt();
}
}
上面是一个抽象类,有四个抽象方法whatHappen、whyHappen、howSolve、haveLearnt,分别对应发生了什么、为什么会发生、怎么解决、心得体会,还有一个调用这四个方法的模板方法getWeeklyReport,只要调用这个方法,就会自动按照这四个套路,把周报给写出来。这个方法定义为final,防止子类进行覆盖。
接下来写两个具体类WeeklyReportOne和WeeklyReportTwo都继承自AbstractWeeklyReport ,只要这两个子类实现了四个抽象方法,然后一调用getWeeklyReport方法,周报就出来了。
//周报一
public class WeeklyReportOne extends AbstractWeeklyReport{
@Override
protected void whatHappen() {
System.out.println("发生了什么:HR总监不给我好脸色");
}
@Override
protected void whyHappen() {
System.out.println("为什么会发生:别人拍他马屁的时候,我在一边冷哼");
}
@Override
protected void howSolve() {
System.out.println("怎么解决:适当的场合,适当地拍一下马屁");
}
@Override
protected void haveLearnt() {
System.out.println("心得体会:拍马屁也是一门手艺"+"\n");
}
}
//周报二
public class WeeklyReportTwo extends AbstractWeeklyReport {
@Override
protected void whatHappen() {
System.out.println("发生了什么:被一条狗追着跑");
}
@Override
protected void whyHappen() {
System.out.println("为什么会发生:当时那条狗兽欲来了,它以为我也是条狗,而且是母的");
}
@Override
protected void howSolve() {
System.out.println("怎么解决:跑到人多的地方让别人遭殃");
}
@Override
protected void haveLearnt() {
System.out.println("心得体会:以后要养条宠物狗,随时带着,以防万一"+"\n");
}
}
接下来写一个测试类,看看运行效果:
public class Client {
public static void main(String[] args) {
AbstractWeeklyReport weeklyReport1 = new WeeklyReportOne();
AbstractWeeklyReport weeklyReport2 = new WeeklyReportTwo();
weeklyReport1.getWeeklyReport();
weeklyReport2.getWeeklyReport();
}
}
运行结果如下:
发生了什么:HR总监不给我好脸色
为什么会发生:别人拍他马屁的时候,我在一边冷哼
怎么解决:适当的场合,适当地拍一下马屁
心得体会:拍马屁也是一门手艺发生了什么:被一条狗追着跑
为什么会发生:当时那条狗兽欲来了,它以为我也是条狗,而且是母的
怎么解决:跑到人多的地方让别人遭殃
心得体会:以后要养条宠物狗,随时带着,以防万一
二、模板方法模式
上面就是一个模板方法模式的例子。
模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。在父类中定义处理流程的框架,在子类中实现具体的处理。
模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。
三、模板方法模式的扩展
写周报写那个心得体会写得恶心极了,实在不想再写,怎么办?可以在父类中增加一个方法isLearnt方法,确定是否有心得体会,没心得体会就不写。在子类中覆盖该方法,确定是否有。
先看抽象类代码:
public abstract class AbstractWeeklyReport {
//发生了什么
protected abstract void whatHappen();
//为什么会发生
protected abstract void whyHappen();
//怎么解决的
protected abstract void howSolve();
//学到了什么
protected abstract void haveLearnt();
//是否有心得体会,默认有
protected boolean isLearnt(){
return true;
}
//生成一篇文章的模板方法
public final void getWeeklyReport(){
whatHappen();
whyHappen();
howSolve();
//先判断是否有心得体会,再决定写不写
if (isLearnt()) {
haveLearnt();
}
}
再看子类的代码:
public class WeeklyReportOne extends AbstractWeeklyReport{
@Override
protected void whatHappen() {
System.out.println("发生了什么:HR总监不给我好脸色");
}
@Override
protected void whyHappen() {
System.out.println("为什么会发生:别人拍他马屁的时候,我在一边冷哼");
}
@Override
protected void howSolve() {
System.out.println("怎么解决:适当的场合,适当地拍一下马屁");
}
@Override
protected void haveLearnt() {
System.out.println("心得体会:拍马屁也是一门手艺"+"\n");
}
@Override
protected boolean isLearnt() {
//周报一,没有心得体会
return false;
}
}
调用getWeeklyReport的结果如下:
发生了什么:HR总监不给我好脸色
为什么会发生:别人拍他马屁的时候,我在一边冷哼
怎么解决:适当的场合,适当地拍一下马屁