一、引言
对于模板方法设计模式,我们在平时的编码过程中,或多或少都用到过,不知道的互啊,可能只是我们并没有注意。本文在分析Thread类的源码的基础上,总结出其中使用的模板方法设计模式。
模板方法设计模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
本文旨在用最通俗易懂的方式对模板方法设计模式进行总结。
二、模板方法介绍我们使用线程有两种方式,第一种方式是extends Thread类,第二种方式实现Runnable接口。这两种方法都必须要实现(或重写)run()方法。这个方法就是模板方法设计模式的核心。
1、Thread类源码分析 (1)、Runable接口public interface Runnable {
public abstract void run();
}
(2)、Thread类实现Runnable接口,会调用Runnable中的run()方法。
public class Thread implements Runnable {
/* What will be run. */
private Runnable target;
//构造方法最终会调用到此方法
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
//代码省略
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
2、模板方法设计模式
模板方法设计模式主要点:
(1)、定义一个抽象类(Abstract Class):该抽象类负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
① 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
② 基本方法:是整个算法中的一个步骤。(可以给不同的子类去实现,抽象方法或者是空方法,反正由子类实现或重写,效果一样)
三、模板方法实例 1、定义一个抽象类public abstract class TemplateMethod {
//模板方法,定义了算法的骨架,此处最好定义为final的,但调用该方法时,会调用该类子类的message()方法
public final void print(String message){
System.out.println("**********************************");
message(message);
System.out.println("**********************************");
}
//基本方法
public abstract void message(String message);
//或者是空方法,让子类覆盖,效果一样
//public void message(String message){};
}
2、抽象类的子类一
public class SubTemplateMethodOne extends TemplateMethod {
@Override
public void message(String message) {
System.out.println("我是来自SubTemplateMethodOne类");
}
}
3、抽象类的子类二
public class SubTemplateMethodTwo extends TemplateMethod {
@Override
public void message(String message) {
System.out.println(message);
}
}
4、测试方法
public static void main(String[] args) {
SubTemplateMethodOne one = new SubTemplateMethodOne();
one.print("我是来自SubTemplateMethodOne类");
System.out.println();
System.out.println();
System.out.println();
SubTemplateMethodTwo two = new SubTemplateMethodTwo();
two.print("我是来自SubTemplateMethodTwo类");
}
5、测试结果
其实模板方法设计模式很简单,核心思想就是:把固定的具体步骤定好后,把变的部分留给各个子类去实现。如果写过APP的朋友,可能对这个方法特别熟悉。
举个例子,比如QQ底部的各个菜单项,初始化每个菜单项的步骤是一样的,只不过各个菜单项请求的接口数据可能不一样,渲染的页面布局不一样,这个就需要各个子类去实现,但请求接口和渲染数据的步骤是一样的,这个就可以用模板方法设计模式。