目录
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。简单来说,就是一些事情的步骤一样,只有具体业务实现不相同,所以将具体业务的实现放在子类中实现。
模板方法模式包含以下主要角色:
比如说炒不同的菜整体步骤相同,但是具体操作不同。
创建抽象类
- //抽象类中包括基本方法以及模板方法
- public abstract class AbstractClass {
- //模板方法
- public final void temp(){
- step1();
- step2();
- step3();
- step4();
- step5();
- }
-
- //基本方法
- public void step1(){
- System.out.println("进行步骤1");
- }
-
- public void step2(){
- System.out.println("进行步骤2");
- }
-
- public abstract void step3();
-
- public abstract void step4();
-
- public void step5(){
- System.out.println("进行步骤5");
- }
- }
不同业务的具体步骤实现
- public class A extends AbstractClass {
- @Override
- public void step3() {
- System.out.println("A业务进行了步骤3");
- }
-
- @Override
- public void step4() {
- System.out.println("A业务进行了步骤4");
- }
- }
-
- public class B extends AbstractClass {
- @Override
- public void step3() {
- System.out.println("B业务进行了步骤3");
- }
-
- @Override
- public void step4() {
- System.out.println("B业务进行了步骤4");
- }
- }
测试
- public class Client {
- public static void main(String[] args) {
- A a = new A();
- a.temp();
- System.out.println("==========");
- B b = new B();
- b.temp();
- }
- }
运行结果如下
进行步骤1
进行步骤2
A业务进行了步骤3
A业务进行了步骤4
进行步骤5
==========
进行步骤1
进行步骤2
B业务进行了步骤3
B业务进行了步骤4
进行步骤5模板方法需要使用final
修饰来防止子类重写修改模板方法实现流程。
InputStream使用到了模板方法模式,在InputStream中存在三个read()
方法
- //使用了abstract修饰,子类必须重写
- public abstract int read() throws IOException;
- //一个参数的read方式实际上调用的参数为三个的read方法
- public int read(byte b[]) throws IOException {
- return read(b, 0, b.length);
- }
-
- public int read(byte b[], int off, int len) throws IOException {
- if (b == null) {
- throw new NullPointerException();
- } else if (off < 0 || len < 0 || len > b.length - off) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return 0;
- }
- //这里调用了无参的read方法,每次读取一个字节
- int c = read();
- if (c == -1) {
- return -1;
- }
- b[off] = (byte)c;
-
- int i = 1;
- try {
- for (; i < len ; i++) {
- c = read();
- if (c == -1) {
- break;
- }
- b[off + i] = (byte)c;
- }
- } catch (IOException ee) {
- }
- return i;
- }
根据文档查看无参的read()作用是读取一个字符,但是我没找到read()在哪里实现了这个读取字符功能。
FileInputStream继承了InputStream,重写了read()方法,执行的是read0()方法,但是无法查看read0()方法的实现代码。
抽象方法是无参的read()方法,模板方法是三个参数的read()方法。通过调用无参的read方法实现一次读取多个字节
read0()方法使用了native关键词修饰,代表调用的是本地方法,所谓本地方法就是非java语言实现的方法,所以无法查看read0()实现源码。