模板方法-高级应用 hook(钩子)

模板方法模式入门: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钩子方法为子类留有选择的余地

钩子hook的其他的表现方式

public final void templateMethod() {
init();
privimitiveOperation1(); //可以是任意位置
doSomeThing();
privimitiveOperation2(); //可以是任意位置
destroy();

if (isHook()) {
hook();
}
}

private boolean isHook() {
return false;
}
//定义为保户方法,对外不可见这个方法
protected void hook() {
//空实现,给子类留有可扩展的余地
}


其中isHook为钩子方法,因为它是决定是否调用括号中的代码,子类可以重写这个方法来决定

hook不是钩子方法,无法决定是否执行这段代码

java钩子hook的应用JFrame的paint方法
例子

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);
}
}


测试结果

————————————————
版权声明:本文为CSDN博主「dengjili」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dengjili/article/details/79657157

猜你喜欢

转载自www.cnblogs.com/yhxb/p/11799565.html