模板方法模式

模板方法模式在一个基类中(抽象类)定义了一个算法(执行过程)的骨架,骨架中有一些步骤可能需要子类自己实现,模板方法模式固定了算法骨架的同时又允许子类自己定义算法中的某些步骤。

比如headfirst中的咖啡和茶的例子,泡咖啡和泡茶的算法其实一样,1烧开水-2冲泡-3倒入杯子-4加作料,只有2/4两步是不一样的。所以我们可以写一个抽象类并定义一个模板方法确定算法框架:

public abstract class Drink {

void getDrink(){
    boilWater();
    brew();
    pourInCup();
    addCondiments();
}

abstract void brew();
abstract void addCondiments();
void boilWater() {
    ... ...  
  }
void pourInCup() {
    ... ...
 }
}

因为2/4两步子类的实现不一样,所以定义为抽象方法让子类自己实现。这样getDrink()就是一个模板方法,它定义了泡茶和泡咖啡共同的算法骨架。



在JDK中也有类似的模式实现,如InputStream中有个read(byte b[], int off, int len) 方法:

 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(),而read()是一个抽象方法,是有子类自己决定如何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()是一个抽象方法:

public abstract int read() throws IOException;

所以我们自己写一个类继承InputStream时必须重写read方法,包括JDK中已有的InputStream子类FileInputStream就重写了:

public int read() throws IOException {
    return read0();
}

private native int read0() throws IOException; //这里也可以看出文件操作是进入内核态进行了系统调用
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容