将具体处理交给子类-template method模式

103 阅读1分钟

1、引入

模板(template),在 百度百科中的解释为模板是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化 。可以理解为建立了一套方案,后续只需要按照方案按部就班即可完成目标(就像英语作文模板)。

而在编程中,亦有template method 设计模式:

  • 在父类中实现了模板方法与抽象方法
  • 在模板方法中调用抽象方法,以完成一套固定的流程
  • 在子类中,只需要实现抽象方法即可

2、案例

定义一模板,会将内容按一定方式打印五次,

2.1、父类AbstractDisplay

public abstract class AbstractDisplay {
    public abstract void open();
    public abstract void print();
    public abstract void close();
    public final void display(){
        open();
        for (int i = 0; i < 5; i++) {
            print();
        }
        close();
    }
}

可以看见,父类中定义了模板-display(),对于它的子类而言,虽然打印出的内容可能会不同,但是整体结构上是一致的

2.2、子类实现之CharDisplay

public class CharDisplay extends AbstractDisplay{
    private char c;

    public CharDisplay(char c) {
        this.c=c;
    }
    @Override
    public void open() {
        System.out.print("<<");
    }

    @Override
    public void print() {
        System.out.print(c);
    }

    @Override
    public void close() {
        System.out.print(">>");
    }
}

2.3、子类实现之StringDisplay

public class StringDisplay extends AbstractDisplay{
    private String s;

    public StringDisplay(String s) {
        this.s=s;
    }

    public void printLine() {
        System.out.print("+");
        for (int i = 0; i < s.length(); i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }

    @Override
    public void open() {
        printLine();
    }

    @Override
    public void print() {
        System.out.println("|"+s+"|");
    }

    @Override
    public void close() {
        printLine();
    }
}

2.4、测试

public class Main {
    public static void main(String[] args) {
        AbstractDisplay stringDisplay = new StringDisplay("Hello World");
        AbstractDisplay charDisplay = new CharDisplay('H');

        stringDisplay.display();
        charDisplay.display();
    }
}

运行上程序,可以得到如下结果

image.png

都有一个开头和结尾,中间内容重复五次,这即所谓模板

3.tips

  • 在display()方法上使用了final,这表明了模板无法被重写,体现了模板之规范不可更改的深刻内涵
  • 模板能够良好的解耦,即如果发现处理流程有问题,只需要修改模板类即可;如果是具体实现有问题,修改特定子类即可