(九)模板方法模式详解(包含与类加载器不得不说的故事) (一)

2014-11-24 10:41:11 · 作者: · 浏览: 1

模板方法模式,这是一个在许多优秀的开源项目中LZ见的最多的一个设计模式,也是LZ觉得最为优秀的一个设计模式,所以这一章LZ会尽自己所能的去尽量将这个设计模式解释清楚。

模板方法模式,一般是为了统一子类的算法实现步骤,所使用的一种手段或者说是方式。它在父类中定义一系列算法的步骤,而将具体的实现都推迟到子类。

最典型的形式就是一个接口,一个抽象父类,父类中会有一系列的抽象方法,而在子类中去一一实现这些方法。

下面LZ给举一个例子,比如我们有一个接口,里面就一个方法,是用来制造一个HTML页面,如下。

[java]
public interface PageBuilder {

String bulidHtml();

}

public interface PageBuilder {

String bulidHtml();

} 这个接口很简单,就是直接制造一个Html页面的内容,假设我们不使用模板方法模式,直接让各个子类去直接实现这个接口,那么肯定实现的方式千奇百怪,而且步骤也乱七八糟的,这样实在不利于维护和扩展。所以我们可以使用模板方法模式,将这个过程给制定好,然后把具体的内容填充交给子类就好,这样这些子类生成的HTML页面就会非常一致。

基于这个目的,我们定义如下抽象类,去实现这个接口,并且我们定义好步骤。

[java]
public abstract class AbstractPageBuilder implements PageBuilder{

private StringBuffer stringBuffer = new StringBuffer();

public String bulidHtml() {
//首先加入doctype,因为都是html页面,所以我们父类不需要推迟给子类实现,直接在父类实现
stringBuffer.append("");
//页面下面就是成对的一个HTML标签,我们也在父类加入,不需要给子类实现
stringBuffer.append("");
//下面就应该是head标签里的内容了,这个我们父类做不了主了,推迟到子类实现,所以我们定义一个抽象方法,让子类必须实现
appendHead(stringBuffer);
//下面是body的内容了,我们父类依然无法做主,仍然推迟到子类实现
appendBody(stringBuffer);
//html标签的关闭
stringBuffer.append("");
return stringBuffer.toString();
}

//第一个模板方法
protected abstract void appendHead(StringBuffer stringBuffer);

//第二个模板方法
protected abstract void appendBody(StringBuffer stringBuffer);

}

public abstract class AbstractPageBuilder implements PageBuilder{

private StringBuffer stringBuffer = new StringBuffer();

public String bulidHtml() {
//首先加入doctype,因为都是html页面,所以我们父类不需要推迟给子类实现,直接在父类实现
stringBuffer.append("");
//页面下面就是成对的一个HTML标签,我们也在父类加入,不需要给子类实现
stringBuffer.append("");
//下面就应该是head标签里的内容了,这个我们父类做不了主了,推迟到子类实现,所以我们定义一个抽象方法,让子类必须实现
appendHead(stringBuffer);
//下面是body的内容了,我们父类依然无法做主,仍然推迟到子类实现
appendBody(stringBuffer);
//html标签的关闭
stringBuffer.append("");
return stringBuffer.toString();
}

//第一个模板方法
protected abstract void appendHead(StringBuffer stringBuffer);

//第二个模板方法
protected abstract void appendBody(StringBuffer stringBuffer);

} 上面LZ已经加了注释,这下我们如果要制作一个html页面,就直接继承我们的抽象父类就可以了,而我们的子类只需要实现两个模板方法,就可以成功完成html页面的创建,下面LZ给出一个子类,我们随意制造一个html页面。

[java]
public class MyPageBuilder extends AbstractPageBuilder{

@Override
protected void appendHead(StringBuffer stringBuffer) {
stringBuffer.append("你好");
}

@Override
protected void appendBody(StringBuffer stringBuffer) {
stringBuffer.append("

你好,世界!

");
}

public static void main(String[] args) {
PageBuilder pageBuilder = new MyPageBuilder();
System.out.println(pageBuilder.bulidHtml());
}

}

public class MyPageBuilder extends AbstractPageBuilder{

@Override
protected void appendHead(StringBuffer stringBuffer) {
stringBuffer.append("你好");
}

@Override
protected void appendBody(StringBuffer stringBuffer) {
stringBuffer.append("

你好,世界!

");
}

public static void main(String[] args) {
PageBuilder pageBuilder = new MyPageBuilder();
System.out.println(pageBuilder.bulidHtml());
}

}