钩子函数的概念源于模板方法模式(Template Method Pattern)
模板方法的核心概念就是,提供一个算法的骨架,将一些算法实现的逻辑,交由子类来完成。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。而钩子函数在这个模式中,就是在抽象父类里,提供了一个默认的方法,父类对这个方法有一个默认的实现(也可不实现),子类可以对这个方法进行重写,从而影响到父类的实现逻辑。
钩子,顾名思义,就是用来挂东西的,模板方法模式中的抽象父类,就是被挂的、被勾住的,而钩子函数,就是哪个钩子,我们可以在钩子的另一端加东西,也可以不加,也就是可以对钩子函数进行重写,或者不重写。
示例:
1、定义抽象客户类
/**
* 抽象客户类
*/
public abstract class AbstractClient {
public String name;
public void registration(){
System.out.println(name+"正在挂号");
}
public void queueUp(){
System.out.println(name+"正在排队");
}
/**
* 具体行为,交由子类实现
*/
public abstract void behavior();
/**
* 评价方法,交由子类实现
*/
public abstract void evaluate();
/**
* 钩子函数
*/
public void hookMethod(){
System.out.println("钩子函数,默认实现");
}
public void TemplateMethod(){
registration();
queueUp();
behavior();
evaluate();
hookMethod();
}
}
2、具体实现类,客户类
public class Client extends AbstractClient {
public Client(String name) {
super(name);
}
@Override
public void behavior() {
System.out.println(name+"正在取钱");
}
@Override
public void evaluate() {
System.out.println(name+"给银行打出了五星好评");
}
//重写钩子函数,实现给银行工作人员打分
@Override
public void hookMethod() {
System.out.println(name+"给银行工作人员打了100分");
}
}
3、运行
public class TemplateMethod {
public static void main(String[] args) {
AbstractClient client = new Client("张三");
client.TemplateMethod();
}
}
4、结果
或者,子类也可以通过钩子函数来控制父类的行为
1、定义抽象父类
public abstract class HookAbstractClass {
//模板方法
public void TemplateMethod() {
if (HookMethod1()) {
SpecificMethod1();
}else{
SpecificMethod2();
}
}
//具体方法
public void SpecificMethod1() {
System.out.println("抽象类中的具体方法1被调用...");
}
//具体方法
public void SpecificMethod2() {
System.out.println("抽象类中的具体方法2被调用...");
}
//钩子方法1
public abstract boolean HookMethod1();
}
2、子类
public class AchieveClass extends HookAbstractClass {
@Override
public boolean HookMethod1() {
return true;
}
}
3、结果
public class HookAbstractClassMain {
public static void main(String[] args) {
HookAbstractClass hookAbstractClass = new AchieveClass();
hookAbstractClass.TemplateMethod();
}
}
子类通过重写HookMethod1()钩子函数,可以实现控制父类的执行逻辑