我们生活中存在着各种模板,比如简历模板、作文模板,模板共性就是将框架固定,具体需要的内容我们需要的时候在进行补充。Template Method模式也是这样,首先定义一个抽象类,然后在这类中定义一个抽象方法,并将里面的抽象方法再在里面作为一个方法(可以理解为实例化,但实际上不是实例化,只是将抽象方法组装成一个固定框架),比如这样:
在抽象类A中,有个方法B3,虽然B3不是抽象方法,但是里面装了3个抽象方法,也就是说,一旦我们调用B3的时候,其实也就相当于调用了其余3个抽象方法,这就相当于给了一个固定的框架。这个会存在误解,抽象方法还没实现怎么能进行调用,注意,这里我们整个类A都是后面需要实现后,这就是Template Method模式的高明之处。
讲这么多,没有例子怎么行呢?可以在java的API中找到。在InputStream中的read()就是这样进行构建的,InputStream是表示字节输入流的所有类的超类,也就是一个抽象类,在这个抽象类中,存在一个抽象方法read(),并且read(byte b[], int off, int len)方法不断第调用抽象方法read(),read(byte b[], int off, int len)就好比上面的B3。附上源码:
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;
}
int c = read(); //这里调用了抽象方法read()
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read(); //这里调用了抽象方法read()
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
话说回来,我们应该怎么使用模板呢?很简单,就是不断实例化抽象方法,拿InputStream来说,它常见的实例化的子类有FileInputStream,在FileInputStream中我们实现的read方法就是具体套用了InputStream的模板。