設(shè)計(jì)模式之模板方法

1. 模板模式

  • 兩大作用
    • 復(fù)用
    • 擴(kuò)展

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

調(diào)用測(cè)試

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

1.2 hook

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

    /** 鉤子方法,默認(rèn)不做任何事,子類可以視情況要不要覆蓋 */
    boolean check() {
        return true;
    }

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

2. 回調(diào)(Callback)

  • 回調(diào)是一種雙向調(diào)用關(guān)系
  • 模板方法容易繼承泛濫,可以利用回調(diào)函數(shù)代替子類繼承
public interface ICallback {
    void before();
    void execute();
}

// 此時(shí)不再是抽象類
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();
    // 往模板方法中注入回調(diào)對(duì)象
    template.execute(new ICallback() {
        @Override
        public void before() {
        }

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

2.1 回調(diào)與模板方法的區(qū)別

  • 回調(diào)基于組合關(guān)系來(lái)實(shí)現(xiàn),模板模式基于繼承關(guān)系來(lái)實(shí)現(xiàn),回調(diào)比模板模式更加靈活
  • 回調(diào)使用匿名類來(lái)創(chuàng)建回調(diào)對(duì)象,可以不用事先定義類;而模板模式針對(duì)不同的實(shí)現(xiàn)都要定義不同的子類

3. 同步回調(diào)與異步回調(diào)

  • 同步回調(diào)指在函數(shù)返回之前執(zhí)行回調(diào)函數(shù)
  • 異步回調(diào)指的是在函數(shù)返回之后執(zhí)行回調(diào)函數(shù)

3.1 同步回調(diào)

同步回調(diào)類似模板模式
Spring提供了很多Template類,比如JdbcTemplate、RedisTemplate、RestTemplate 都是基于回調(diào)來(lái)實(shí)現(xiàn)的

3.2 異步回調(diào)

例如:事件監(jiān)聽(tīng)器,即傳遞一個(gè)包含回調(diào)函數(shù)(onClick())的對(duì)象給另一個(gè)函數(shù)

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 很關(guān)鍵
            response.handler(this, request);
        }).start();
        System.out.println("end...");
    }

    @Override
    public void callback(String result) {
        System.out.println("異步回調(diào)結(jié)果:" + 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);
    }
}

測(cè)試:

public static void main(String[] args) {
    Template template = new Template(new CallbackResponse());
    template.execute("request");
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容