模板方法模式
定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
一、常见使用的场景
如 Thread 类。我们知道在 Java 中一种使用多线程的方式是定义一个类继承 Thread 类然后重写其中的 run 方法,此时 run 方法中的逻辑是由我们去自己写的,通过调用 start() 方法我们可以使得创建好的线程进入 可运行状态 然后 JVM 会去调用对应的 run 方法执行。
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
二、简单示例
上面常见场景会有些抽象,应为有些东西对我们是不可见的,所以这里通过一个简单例子理解。
首先我们定义一个父类
此类:定义了一个算法的步骤,类似于 Thread 定义类需要线程执行的代码 run 的被调用步骤(即:这个方法在一个执行流程中,这个流程虽然我们没有办法控制,但是流程中的具体步骤我们可以根据具体情况实现)
package templatemethod;
/**
* 模板方法类:可以看到这里我们只是给了一个做西红柿炒鸡蛋的步骤(一个算法步骤)
*/
public abstract class Cook {
abstract void oil(); // 食用油
abstract void egg(); // 鸡蛋
abstract void tomato(); // 西红柿
// 封装具体的行为:做饭
public final void cook() {
this.oil();
this.egg();
this.tomato();
}
}
然后我们编写两个子类
这两个类就类似于你编写了两个不同的类继承 Thread 类并重写了 run 方法
package templatemethod;
/**
* 定义一个我的类
*/
public class Me extends Cook{
@Override
void oil() {
System.out.println("自己:油放多了");
}
@Override
void egg() {
System.out.println("自己:鸡蛋糊了");
}
@Override
void tomato() {
System.out.println("自己:番茄没熟");
}
}
package templatemethod;
/**
* 定义一个厨师类
*/
public class Chef extends Cook{
@Override
void oil() {
System.out.println("厨师:油适量");
}
@Override
void egg() {
System.out.println("厨师:鸡蛋煎至金黄");
}
@Override
void tomato() {
System.out.println("厨师:番茄炒至入味");
}
}
测试
package templatemethod;
/**
* 测试调用类
*/
public class Main {
public static void main(String[] args) {
new Chef().cook();
new Me().cook();
}
}
// 输出:
厨师:油适量
厨师:鸡蛋煎至金黄
厨师:番茄炒至入味
自己:油放多了
自己:鸡蛋糊了
自己:番茄没熟
三、总结
适用于处理某一个流程的代码我们已经可以确定,但是其中某一个或以上的具体步骤我们暂时不能确定,因此通过模板方法模式,将这个步骤中的一步或者几步的具体实现转交给子类完成。即:处理步骤父类中定义好,具体实现延迟到子类中定义。
标签:定义,模版,void,模式,步骤,println,方法,public,out From: https://www.cnblogs.com/fragmentary/p/18380020