模板方法模式入门: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