• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

设计模式:模板方法

武飞扬头像
Tinyspot
帮助1

1. 模板模式

  • 两大作用
    • 复用
    • 扩展

1.1 示例

  1. 抽象父类
  2. 抽象方法
  • 需要子类重写的定义为抽象方法(子类按需重写方法)
  • 不让子类覆盖的方法定义为 final
public abstract class Template {
    
    // 模板方法,使用final约束不能轻易修改
    public final void execute() {
        step1();
        step2();
        step3();
    }

    // 抽象方法
    abstract void step2();

    protected void step1() {
        // do something
    }
    protected void step3() {
        // do something
    }
}
public class ConcreteTemplate extends Template {
    @Override
    void step2() {
        // do something
    }
}

调用测试

Template template = new ConcreteTemplate();
template.execute();

1.2 hook

  • 钩子方法,加一个 boolean 方法
public abstract class Template {
    public final void execute() {
        step1();
        if (check()) {
            step2();
        }
        step3();
    }

    /** 钩子方法,默认不做任何事,子类可以视情况要不要覆盖 */
    boolean check() {
        return true;
    }

    // ... 此处省略其他方法
}

2. 回调(Callback)

  • 回调是一种双向调用关系
  • 模板方法容易继承泛滥,可以利用回调函数代替子类继承
public interface ICallback {
    void before();
    void execute();
}

// 此时不再是抽象类
public final class Template {
    public void execute(ICallback callback) {
        show();
        callback.before();
        callback.execute();
    }

    private void show() {
        // do something
    }
}
public static void main(String[] args) {
    Template template = new Template();
    // 往模板方法中注入回调对象
    template.execute(new ICallback() {
        @Override
        public void before() {
        }

        @Override
        public void execute() {
        }
    });
}

2.1 回调与模板方法的区别

  • 回调基于组合关系来实现,模板模式基于继承关系来实现,回调比模板模式更加灵活
  • 回调使用匿名类来创建回调对象,可以不用事先定义类;而模板模式针对不同的实现都要定义不同的子类

3. 同步回调与异步回调

  • 同步回调指在函数返回之前执行回调函数
  • 异步回调指的是在函数返回之后执行回调函数

3.1 同步回调

同步回调类似模板模式
Spring提供了很多Template类,比如JdbcTemplate、RedisTemplate、RestTemplate 都是基于回调来实现的

3.2 异步回调

例如:事件监听器,即传递一个包含回调函数(onClick())的对象给另一个函数

public interface ICallback {
    void callback(String result);
}

public class Template implements ICallback {

    private CallbackResponse response;

    public Template(CallbackResponse response) {
        this.response = response;
    }

    public void execute(String request) {
        System.out.println("start...");
        new Thread(() -> {
            // this 很关键
            response.handler(this, request);
        }).start();
        System.out.println("end...");
    }

    @Override
    public void callback(String result) {
        System.out.println("异步回调结果:"   result);
    }
}
public class CallbackResponse {
    public void handler(ICallback callback, String request) {
        String result = null;
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        result = request   " ok";
        callback.callback(result);
    }
}

测试:

public static void main(String[] args) {
    Template template = new Template(new CallbackResponse());
    template.execute("request");
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgkbhbk
系列文章
更多 icon
同类精品
更多 icon
继续加载