stringBuffer.append("");
}
protected void appendTitle(StringBuffer stringBuffer) {
stringBuffer.append("
}
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{
protected void appendMeta(StringBuffer stringBuffer) {
stringBuffer.append("");
}
protected void appendTitle(StringBuffer stringBuffer) {
stringBuffer.append("
}
protected void appendBody(StringBuffer stringBuffer) {
stringBuffer.append("
}
public static void main(String[] args) {
PageBuilder pageBuilder = new MyPageBuilder();
System.out.println(pageBuilder.bulidHtml());
}
}
我们覆盖了appendMeta方法,所以我们就可以在head标签中生成一个meta标签。如果各位看过上章的适配器模式,其实这里和缺省适配很像,目的都是一样的,因为如果把appendMeta也写成抽象方法,那么子类就必须实现,但是meta标签又不是必须的,所以子类就有可能把appendMeta,appendLink,appendScript方法全空着了。
所以为了不强制子类实现不必要的抽象方法,但又不剥夺子类自由选择的权利,我们在父类提供一个默认的空实现,来让子类自由选择是否要覆盖掉这些方法。
说到模板方法模式,我们JDK当中有一个类与它还有一个不得不说的故事,那就是类加载器。
JDK类加载器可以大致分为三类,分别是启动类加载器,扩展类加载器,以及应用程序加载器。
这三者加载类的路径分别为如下:
启动类加载器:JAVA_HOME/lib目录下,以及被-Xbootcalsspath参数设定的路径,不过启动类加载器加载的类是有限制的,如果JVM不认识的话,你放在这些目录下也没用。
扩展类加载器:JAVA_HOME/lib/ext目录下,以及被java.ext.dirs系统变量指定的路径。
应用程序类加载器:用户自己的类路径(classpath),这个类加载器就是我们经常使用的系统类加载器,并且JDK中的抽象类ClassLoader的默认父类加载器就是它。
在这里为什么说类加载器和模板方法模式有关呢,是因为ClassLoader类就使用了模板模式,去保证类加载过程中的唯一性。LZ先给各位看下这个类当中的模板模式的应用。
[java]
public abstract class ClassLoader {
//这是一个重载方法
public Class< > loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
//这里就是父类算法的定义
protected synchronized Class< > loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
//这里留了一个方法给子类选择性覆盖
protected Class< > findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}
public abstract class ClassLoader {
//这是一个重载方法
public Class< > loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
//这里就是父类算法的定义
protected synchronized Class< > loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
//这里留了一个方法给子类选择性覆盖
protected Class< > findClass(String name) throw