Java设计模式之——模板方法模式(Template)

来源:互联网 发布:淘宝二手名表是真的吗 编辑:程序博客网 时间:2024/06/06 03:54

毕业没多久在东莞的一家制造业企业找了份工作,刚进去是在人力资源部干活,每天给新进来的员工培训,为期三天。培训企业文化、公司规章制度、生产安全、静电放电等。当时是储干(储着被干),而且有好多个,顶头上司是一个培训专员。他喜欢每周四让我们给他写一篇周报,每个人对此都深恶痛绝,又不得不写。当时有个同事,不知道该写什么,怎么写。我就在边上忽悠他,按照四个幼稚地步骤去写: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总监不给我好脸色
为什么会发生:别人拍他马屁的时候,我在一边冷哼
怎么解决:适当的场合,适当地拍一下马屁

0 0
原创粉丝点击