硬核空间技术博客

图解设计模式之Template Method模式

2020-04-03  本文已影响0人  憨憨二师兄

什么是 Template Method模式

Template Method即模板方法,组成模板的方法被定义在父类中,而在子类中实现父类中定义的这些抽象方法。虽然子类中实现了父类的抽象方法,都有各自的实现,但是在父类定义了处理流程的框架,无论子类中的具体实现如何,处理的流程都会按照父类中所定义的那样进行,这种设计模式就是Template Method模式。

示例程序

示例程序比较简单,UML图如下:


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();
    }
}

AbstractDisplay类中,定义了三个抽象方法,由子类继承实现。而display方法则是处理流程的框架。display方法中,首先调用了open方法,然后调用了五次print方法,最后调用了close方法。至于open,print,close方法的具体实现交给继承AbstractDisplay的子类,而整体的框架流程,则是由父类的模板所定义出来的。

CharDisplay 类

public class CharDisplay extends AbstractDisplay{
    private char ch;
    public CharDisplay(char ch){
        this.ch = ch;
    }
    public void open(){
        System.out.print("<<");
    }
    public void print(){
        System.out.print(ch);
    }
    public void close(){
        System.out.println(">>");
    }
}

当向CharDisplay类的构造函数中传入A这个字符串,那么最终显示的结果为:

<<AAAAA>>
StringDisplay 类
public class StringDisplay extends AbstractDisplay{
    private String string;
    private int length;
    public StringDisplay(String string){
        this.string = string;
        this.length = string.length();
    }
    
    public void open(){
        printLine();
    }
    public void print(){
        System.out.println("|" + string + "|");
    }
    public void close(){
        printLine();
    }
    private void printLine(){
        System.out.print("+");
        for(int i = 0;i < length;i++){
            System.out.print("-");
        }
        System.out.println("+");
    }
}

当向StringDisplay类的构造器中传入字符串Dobby时,输出如下:

+-----+
|Dobby|
|Dobby|
|Dobby|
|Dobby|
|Dobby|
+-----+

Main类

public class Main{
    public static void main(String[] args){
        AbstractDisplay d1 = new CharDisplay('H');
        AbstractDisplay d2 = new StringDisplay("Dobby");
        d1.display();
        d2.display();
    }
}

程序显示结果如下:

<<HHHHH>>
+-----+
|Dobby|
|Dobby|
|Dobby|
|Dobby|
|Dobby|
+-----+

Template Method模式中的角色

AbstractClass

AbstractClass负责实现模板方法,并且声明模板方法中所使用的抽象方法,这些抽象方法由继承它的子类来负责具体的实现。示例程序中由AbstractDisplay扮演这个角色。

ConcreteClass

负责实现AbstractClass中的抽象方法,示例程序中CharDisplay与StringDisplay扮演此角色。

Template Method的UML图

对Template Method模式的思考

为什么使用 Template Method模式

使用模板方法模式的好处就在于,我们将算法编写到了父类中,无需再在子类里面定义算法的流程了。拿另外一个例子说明,比如做菜。做菜这件事,将基本的流程定义好:第一步,洗锅;第二步,放油;第三部,放菜;第四部,放调味料,第五步,炒菜......当做菜的流程被定义好,那么无论是西红柿炒鸡蛋,还是尖椒炒牛肉,都会按照做菜这个模板方法来进行,当然具体的步骤如放多少盐,倒多少油是做什么菜来决定的。试想一下没有模板方法,那么菜谱中每个菜的做法都被独立开,就会有大量的重复流程说明,模板方法的意义不仅仅在于定义算法的流程,更在于体现出了继承的优势,大大减少了重复的步骤,缩减了代码量。

为什么模板方法要使用final

如果使用了final定义模板方法,那么意图其实很明显,就是继承AbstractClass的子类无法重写模板方法。

上一篇下一篇

猜你喜欢

热点阅读