模板方法模式

Posted peterxiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板方法模式相关的知识,希望对你有一定的参考价值。

  这是一个在许多优秀的开源项目中LZ见的最多的一个设计模式,也是LZ觉得最为优秀的一个设计模式。

  模板方法模式,一般是为了统一子类的算法实现步骤,所使用的一种手段或者说是方式。它在父类中定义一系列算法的步骤,而将具体的实现都推迟到子类。

  下面LZ给举一个例子,比如我们有一个接口,里面就一个方法,是用来制造一个html页面,如下。

public interface PageBuilder{
    String buildHtml();
}

  这个接口很简单,就是直接制造一个html页面内容,假设不使用模板方法模式,直接让各个子类去直接实现这个接口,那么肯定实现的方式多种多样,而且步骤也乱七八糟,这样不利于维护和扩展。所以我们可以使用模板方法模式,将这个过程给制定好,然后把具体的内容填充交给子类就好,这样这些子类生成的HTML页面就会一致。

  基于这个目的,我们定义如下抽象类,去实现这个接口,并且我们定义好步骤。

public abstract class AbstractPageBuilder implements PageBuilder{

    private static final String DEFAULT_DOCTYPE = "<!DOCTYPE HTML>";

    private StringBuffer stringBuffer = new StringBuffer();

    public String bulidHtml() {
        stringBuffer.append(DEFAULT_DOCTYPE);
        stringBuffer.append("<html>");
        stringBuffer.append("<head>");
        appendTitle(stringBuffer);
        appendMeta(stringBuffer);
        appendLink(stringBuffer);
        appendScript(stringBuffer);
        stringBuffer.append("</head>");
        appendBody(stringBuffer);
        stringBuffer.append("</html>");
        return stringBuffer.toString();
    }
    //供子类选择性覆盖
    protected void appendMeta(StringBuffer stringBuffer){
    }
    //供子类选择性覆盖
    protected void appendLink(StringBuffer stringBuffer){
    }
    //供子类选择性覆盖
    protected void appendScript(StringBuffer stringBuffer){
    }
   //模板方法 添加标题
    protected abstract void appendTitle(StringBuffer stringBuffer);
   //模板方法 添加body
    protected abstract void appendBody(StringBuffer stringBuffer);

}

  子类只要实现两个模板方法,就可以成功创建html页面。

public class MyPageBuilder extends AbstractPageBuilder{
    
    protected void appendMeta(StringBuffer stringBuffer) {
        stringBuffer.append("<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />");
    }

    protected void appendTitle(StringBuffer stringBuffer) {
        stringBuffer.append("<title>你好</title>");
    }

    protected void appendBody(StringBuffer stringBuffer) {
        stringBuffer.append("<body>你好,世界!</body>");
    }

    public static void main(String[] args) {
        PageBuilder pageBuilder = new MyPageBuilder();
        System.out.println(pageBuilder.bulidHtml());
    }
    
}

  meta,link和script是留给子类覆盖的,当然子类可以选择不覆盖,那么生成的HTML就没有meta,link和script这三种标签,如果想有的话,就可以覆盖其中任意一个。

  为了不强制子类实现不必要的抽象方法,但又不剥夺子类自由选择的权利,我们在父类提供一个默认的空实现,来让子类自由选择是否要覆盖掉这些方法。

 

以上是关于模板方法模式的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段2——.vue文件的模板

VSCode自定义代码片段(vue主模板)

VS Code配置snippets代码片段快速生成html模板,提高前端编写效率

设计模式模板方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )