模板方法模式入门:https://blog.csdn.net/dengjili/article/details/79631472
加入hook,其中这个hook方法是可选的
给出例子,再给出解释
package headfirst.hd.template.eg;
public abstract class AbstractClass {
//不让子类覆盖掉这个方法,声明为final类型
//父类定义程序执行模板
public final void templateMethod() {
init();
privimitiveOperation1(); //可以是任意位置
doSomeThing();
privimitiveOperation2(); //可以是任意位置
destroy();
hook();
}
//定义为保户类型,对外不可见这个方法
protected void hook() {
//空实现,给子类留有可扩展的余地
}
public void init() {
System.out.println("这是父类一个初始化init方法,需要做很多事情");
}
public void destroy() {
System.out.println("这是父类一个初始化destroy方法,需要做很多事情\n");
}
public void doSomeThing() {
System.out.println("做很多事情");
}
//一般抽象方法数据不是很多
public abstract void privimitiveOperation1();
public abstract void privimitiveOperation2();
}
子类一,不重写hook方法
package headfirst.hd.template.eg;
public class ConcreteClass extends AbstractClass {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass,子类方法2,做了很多事情");
}
}
子类二,重写hook方法
package headfirst.hd.template.eg;
public class ConcreteClass2 extends AbstractClass {
@Override
public void privimitiveOperation1() {
System.out.println("类ConcreteClass2,子类方法1,做了很多事情");
}
@Override
public void privimitiveOperation2() {
System.out.println("类ConcreteClass2,子类方法2,做了很多事情");
}
@Override
protected void hook() {
System.out.println("类ConcreteClass2,钩子方法,增加一些附加功能");
}
}
测试代码
package headfirst.hd.template.eg;
public class Client {
//模板方法模式:定义程序执行流程,子类实现部分步骤
public static void main(String[] args) {
AbstractClass temlate = new ConcreteClass();
temlate.templateMethod();
//更换第二个子类,程序执行流程不变
temlate = new ConcreteClass2();
temlate.templateMethod();
}
}
测试结果
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass,子类方法1,做了很多事情
做很多事情
类ConcreteClass,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
这是父类一个初始化init方法,需要做很多事情
类ConcreteClass2,子类方法1,做了很多事情
做很多事情
类ConcreteClass2,子类方法2,做了很多事情
这是父类一个初始化destroy方法,需要做很多事情
类ConcreteClass2,钩子方法,增加一些附加功能
结论,子类得出结论,hook钩子方法为子类留有选择的余地
public final void templateMethod() {
init();
privimitiveOperation1(); //可以是任意位置
doSomeThing();
privimitiveOperation2(); //可以是任意位置
destroy();
if (isHook()) {
hook();
}
}
private boolean isHook() {
return false;
}
//定义为保户方法,对外不可见这个方法
protected void hook() {
//空实现,给子类留有可扩展的余地
}
其中isHook为钩子方法,因为它是决定是否调用括号中的代码,子类可以重写这个方法来决定
hook不是钩子方法,无法决定是否执行这段代码
例子
package callback.other;
import javax.swing.JFrame;
public class TestFrame extends JFrame {
private static final long serialVersionUID = 1L;
public TestFrame() {
super("钩子hook");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setVisible(true);
}
}
测试
package callback.other;
public class MyFrame {
public static void main(String[] args) {
new TestFrame();
}
}
测试结果
调用钩子方法paint
package callback.other;
import java.awt.Graphics;
import javax.swing.JFrame;
public class TestFrame extends JFrame {
private static final long serialVersionUID = 1L;
public TestFrame() {
super("钩子hook");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setVisible(true);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawString("钩子重写方法", 180, 180);
}
}