美文网首页
模板方法模式 -- 将具体处理交给子类

模板方法模式 -- 将具体处理交给子类

作者: 戴廿叁 | 来源:发表于2019-08-21 13:08 被阅读0次

1. 概述

可能你没有注意,但模板方法模式是被广泛应用在日常开发中的一种基本模式。事实上,当你使用继承或者多态概念的时候,就正在使用模板方法模式。
简单地说,Template method 就是将处理流程抽象出来,构成一个模板(父类)。模板并不关心具体的实现,而是把处理逻辑交给模板的实现(子类)。查看父类的代码是无法了解这些方法最终会如何进行处理,只有子类才决定具体的逻辑。但是无论子类如果处理,都会遵循父类的流程框架。

像这样在父类中定义处理流程的框架,在子类中实现具体处理的模式就被称为 Template method 模式。

2. 模式类图

template-1.png

3. 模式角色

AbstractClass AbstractClass 负责实现模板,同时负责声明模板中的抽象方法。这些抽象方法由子类 ConcreteClass 角色负责实现。
ConcreteClass ConcreteClass 负责实现 AbstractClass 角色中定义的抽象方法。

4. 代码示例

假设我们想将一段字符或者字符串循环打印5次,我们要怎么做呢?程序对于字符和字符串的打印处理是不同的,但是处理流程本身却是相同的(打印5次),这样的情况,就很适合使用模板方法模式。

我们先定义一个抽象类 AbstractDisplay,这个类会定义一个display方法,而这个方法会依次调用 open 、print 、 close 这3个方法。虽然这3个都被声明了,但是并没有方法体实现。在这里,调用抽象方法的 display 方法就是模板方法

AbstractDisplay.java

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

}

之后,我们为打印字符和字符串分别定义各自的实现类 CharDisplay 和 StringDisplay

CharDisplay.java

public class CharDisplay extends AbstractDisplay {
    private char ch;

    public CharDisplay(char ch) {
        this.ch = ch;
    }

    @Override
    public void open() {
        System.out.print("<<");
    }

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

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

调用方式

AbstractDisplay charDisplay = new CharDisplay('A');
charDisplay.display();

输出结果为

<<AAAAA>>

StringDisplay.java

public class StringDisplay extends AbstractDisplay {
    private String string;

    private int width;

    public StringDisplay(String string) {
        this.string = string;
        this.width = string.getBytes().length;
    }

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

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

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

    private void printLine() {
        System.out.print("+");
        for (int i = 0; i < this.width; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }
}

调用方式

AbstractDisplay stringDisplay = new StringDisplay("Hello world");
stringDisplay.display();

输出结果为

+-----------+
|Hello world|
|Hello world|
|Hello world|
|Hello world|
|Hello world|
+-----------+

5. 延展阅读

模板方法模式的优势

Template method 的优点显而易见,由于在父类的模板方法中已经编写是算法(display),因此无需在每个子类中再去编写相同逻辑的算法。这就是所谓使逻辑处理通用化。

抽象类的意义?

对于抽象类,我们无法生成其实例。在初学抽象类的时候,有人会这样问:“无法生成实例的类有什么用呢?” 在理解 Template method 模式之后,大家应该能够稍微体会到抽象类的意义了吧。由于在抽象类中没有编写具体的实现,所以我们无法知道在抽象类中到底进行了什么处理。但是我们可以决定抽象方法的名字,然后通过调用使用了这些抽象方法的模板方法去编写处理。虽然具体的处理逻辑是由子类实现的,不过在抽象类阶段确定处理的流程非常重要。

父类与子类的一致性

在实例代码中,无论是 CharDisplay 的实例还是 StringDisplay 的实例,都是保存在 AbstractDisplay 类型变量中的,然后再来调用 display 方法。使用父类型保存子类型的优点是,即使没有用 instanceof 等指定子类的种类,程序也可以正常工作。这种原则成为里氏替换原则(The Liskov Substitution Priciple, LSP)。

相关文章

  • 14.模板方法模式

    将具体处理交给子类 是什么 在父类中(通常是抽象类)定义处理流程的框架,在子类中实现具体处理的模式就是模板方法模式...

  • 模板方法模式 -- 将具体处理交给子类

    1. 概述 可能你没有注意,但模板方法模式是被广泛应用在日常开发中的一种基本模式。事实上,当你使用继承或者多态概念...

  • 行为型设计模式详解之模板方法模式!深度解析模板方法模式的使用和实

    模板方法模式 模板方法模式: 使用一个抽象类定义算法模板结构,将某些具体算法步骤的实现延迟到子类中进行,使得子类在...

  • 工厂模式(Factory Method)

    1、什么是工厂模式 在上一节的模块方法设计模式(交给子类)中,模式中,将方法的具体实现交给了子类,而父类只负责规定...

  • 15.工厂方法模式

    在模板方法模式中,在父类(抽象类)中定义流程,将具体实现交由子类实现,如果将模板方法模式用于生成实例对象,那么模板...

  • 16.桥梁模式

    在模板方法模式中,在父类(抽象类)中定义流程,将具体实现交由子类实现,如果将模板方法模式用于生成实例对象,那么模板...

  • 模板模式

    模板模式 asynctask 就是模板模式 定义: 定义一个操作流程的骨架,然后将一些步骤的具体实现放到子类中. ...

  • template模式

    模板模式(template) 定义 模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构...

  • Lambda表达式在模板模式中的应用

    模板模式 模板模式在父类(抽象类)中实现算法的框架,将算法中的具体步骤放在子类(具体类)中实现。 其中算法的各个步...

  • 模板模式

    模板模式 定义 模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不...

网友评论

      本文标题:模板方法模式 -- 将具体处理交给子类

      本文链接:https://www.haomeiwen.com/subject/slrbsctx.html