设计模式之模板模式

115 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

前言

我想大家应该都写过简历,没人一上来就凭着感觉走,想到哪就写到哪吧。我们首先肯定是先到网上搜索下简历模板,然后按照模板一步步来编写我们的简历。

模板模式到底是什么

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

钩子方法

先聊聊钩子方法,因为下面代码会用到

他是由抽象类声明并且实现,子类也可以选择加以扩展。通常抽象类会给出一个空的钩子方法,也就是没有实现的扩展。

它和具体方法在代码上没有区别,不过是一种意识的区别;而它和抽象方法有时候也是没有区别的,就是在子类都需要将其实现的时候。

而不同的是抽象方法必须实现,而钩子方法可以不实现。也就是说钩子方法为你在实现某一个抽象类的时候提供了可选项,相当于预先提供了一个默认配置。

举个例子

我们就用编写简历来看看这个模板模式吧

首先我们需要定义一个简历模板,也就是一个模板抽象类。

然后简历模板大概分几块

  • 个人简介
  • 工作意向
  • 专业技能
  • 项目经验
  • 自我评价 我们将它变成代码看看
/**
 * 简历模板
 */
abstract class ResumeTemplate{
    /**
     * 个人简介
     */
    abstract void personalProfile();

    /**
     * 工作意向
     */
    abstract void jobIntention();

    /**
     * 专业技能
     */
    abstract void professionalSkills();

    /**
     * 项目经验
     */
    abstract void projectExperience();

    /**
     * 自我评价
     */
    abstract void selfEvaluation();

    /**
     * 编写简历输出
     */
    void out(){
        personalProfile();
        jobIntention();
        professionalSkills();
        projectExperience();
        if (isSelfEvaluation()){
            selfEvaluation();
        }
    }

    /**
     * 钩子方法:是否需要自我评价,默认需要
     * @return
     */
    boolean isSelfEvaluation(){
        return true;
    }
}

我们可以看到这个模板抽象类里面定义了一个钩子方法。他主要的作用就是用来控制自我评价方法是否需要参加到简历的编写中

接着我们根据简历模板来真正的编写简历,先写个程序员简历。

class ProgrammerResume extends ResumeTemplate{

    @Override
    void personalProfile() {
        System.out.println("我叫木木文");
    }

    @Override
    void jobIntention() {
        System.out.println("想找个月薪两千的Java开发工作");
    }

    @Override
    void professionalSkills() {
        System.out.println("会写Java代码");
    }

    @Override
    void projectExperience() {
        System.out.println("在某互联网小厂干了一段时间Java开发");
    }

    @Override
    void selfEvaluation() {
        System.out.println("我是一个乐观好学的90后");
    }

    @Override
    boolean isSelfEvaluation() {
        // 程序员简历默认不编写自我评价
        return false;
    }
}

再写个老师简历

class TeacherResume extends ResumeTemplate{

    private boolean isSelfEvaluation;

    public void setSelfEvaluation(boolean isSelfEvaluation) {
        this.isSelfEvaluation = isSelfEvaluation;
    }

    @Override
    void personalProfile() {
        System.out.println("我叫小小汪");
    }

    @Override
    void jobIntention() {
        System.out.println("想找个月薪两千的英语老师");
    }

    @Override
    void professionalSkills() {
        System.out.println("会教孩子们英语");
    }

    @Override
    void projectExperience() {
        System.out.println("在某教育机构干了一段时间英语老师");
    }

    @Override
    void selfEvaluation() {
        System.out.println("我是一个乐观善良的90后");
    }

    @Override
    boolean isSelfEvaluation() {
        // 老师的简历自己选择是否编写自我评价
        return this.isSelfEvaluation;
    }
}

我们对比程序员简历和老师简历类发现,他们通过重写钩子方法来达到控制自我评价方法是否参与简历输出的目的

写个main方法看看效果吧

public static void main(String[] args) {
    System.out.println("程序员编写简历start");
    ProgrammerResume programmerResume = new ProgrammerResume();
    programmerResume.out();
    System.out.println("程序员编写简历end");

    System.out.println("\n=======================");
    System.out.println("老师编写简历start");
    TeacherResume teacherResume = new TeacherResume();
    teacherResume.setSelfEvaluation(true);
    teacherResume.out();
    System.out.println("老师编写简历end");
}

image.png

这样我们就实现了一个通过简历模板编写不同职业简历的功能了

参考书籍、资料

  • 《设计模式之禅》