模板方法-高级应用 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);
    }
}

测试结果
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值