首頁 > Java > java教程 > 主體

Java設計模式之模板方法實例分析

WBOY
發布: 2023-05-14 14:43:06
轉載
1226 人瀏覽過

概念

範本方法模式是所有模式中最常見的幾個模式之一,是基於繼承的程式碼重複使用的基本技術,沒有關聯關係。因此,在模板方法模式的類別結構圖中,只有繼承關係。

核心設計重點

AbstractClass:抽象類,定義並實作一個模板方法。這個模板方法定義了演算法的骨架,而邏輯的組成步驟在對應的抽像操作中,延後到子類別去實作。

ConcreteClass:實作由父類別定義的一個或多個抽象方法。

優缺點

優點

  • 利用範本方法將相同處理邏輯的程式碼放到抽象父類別中,可以提高程式碼的重複使用性。

  • 將不同的程式碼不同的子類別中,透過子類別的擴充增加新的行為,提高程式碼的擴充性。

  • 把不變的行為寫在父類別.上,移除子類別的重複程式碼,提供了一個很好的程式碼重複使用平台,符合開閉原則。

缺點

類別數目的增加,每一個抽象類別都需要一個子類別來實現,這樣導致類別的個數增加,複雜性增加。類別數量的增加,間接增加了系統實現的複雜度。繼承關係本身缺點,如果父類別加入新的抽象方法,所有子類別都要改一-遍。

應用場景

  • 父類別觀點:一次實作一個演算法不變的部分,將可變部分留給子類別實作;

  • 子類別觀點:各個子類別中,公共部分被提取出來,集中到一個公共的父類別中,避免程式碼重複;

模板方法模式的目的是讓子類別可以擴展或具體實現固定方法的某個具體的步驟;對於模板來說,是一套固定的演算法,透過子類別可以擴展固定演算法中某些演算法步驟。

模板方法和策略模式的區別

策略模式是對演算法的封裝,把一系列的演算法分別封裝到對應的類別中,並且這些類別實現相同的接口,相互之間可以替換。還有一種模

式也是關注演算法的封裝一模版方法模式,對照類別圖可以看到,策略模式與模版方法模式的區別僅僅是多了一個單獨的封裝類別

Context,它與模版方法模式的區別在於:在模版方法模式中,調用演算法的主體在抽象的父類中,而在策略模式中,調用演算法的主

#體則是封裝到了封裝類別Context中,抽象策略Strategy一般是一個接口, 目的只是為了定義規範,裡面一般不包含邏輯。其實,這只是通用實現,而在實際程式設計中,因為各個具體策略實現類別之間難免存在–些相同的邏輯,為了避免重複的程式碼,我們常常使用抽象類別來擔任Strategy的角色,在裡面封裝公共的程式碼,因此,在許多應用的場景中,在策略模式中- -般會看到模版方法模式的影子。

程式碼案例

模版方法抽象類別

@Slf4j
public abstract class AbstractPayCallbackTemplate {
    /**
     * 异步回调业务
     *
     * @return
     */
    public String asyncCallBack() {
        // 1. 支付回调验证参数
        Map<String, String> verifySignatureMap = verifySignature();
        // 2. 参数验证成功,写入日志中..
        payLog(verifySignatureMap);
        String analysisCode = verifySignatureMap.get("analysisCode");
        if (!analysisCode.equals("200")) {
            return resultFail();
        }
        // 3. 执行回调异步相关逻辑
        return asyncService(verifySignatureMap);
    }
    /**
     * 支付回调验证参数
     *
     * @return
     */
    protected abstract Map<String, String> verifySignature();
    /**
     * 使用多线程异步写入日志
     *
     * @param verifySignatureMap
     */
    @Async
    void payLog(Map<String, String> verifySignatureMap) {
        log.info(">>>>>>>>>>第二步 写入payLog........");
    }
    /**
     * 每个子类需要实现 实现业务解析操作
     *
     * @return
     */
    protected abstract String asyncService(Map<String, String> verifySignatureMap);
    /**
     * 异步返回结果..
     *
     * @return
     */
    protected abstract String resultSuccess();
    /**
     * 异步返回失败
     *
     * @return
     */
    protected abstract String resultFail();
}
登入後複製

具體實作模版類別

@Log4j2
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1399");
        verifySignature.put("orderDes", "充值永久会员");
        // 支付状态为1表示为成功....
        verifySignature.put("aliPayMentStatus", "1");
        verifySignature.put("aliPayOrderNumber", "201910101011");
        // 解析报文是否成功 200 为成功..
        verifySignature.put("analysisCode", "200");
        return verifySignature;
    }
    @Override
    protected String asyncService(Map<String, String> verifySignatureMap) {
        log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
        String paymentStatus = verifySignatureMap.get("aliPayMentStatus");
        if (paymentStatus.equals("1")) {
            String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber");
            log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付...");
        }
        return resultSuccess();
    }
    @Override
    protected String resultSuccess() {
        return "ok";
    }
    @Override
    protected String resultFail() {
        return "fail";
    }
}
@Slf4j
public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 解析银联数据报文.....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1399");
        verifySignature.put("orderDes", "充值永久会员");
        // 支付状态为1表示为成功....
        verifySignature.put("paymentStatus", "1");
        verifySignature.put("orderNumber", "201910101011");
        // 解析报文是否成功 200 为成功..
        verifySignature.put("analysisCode", "200");
        return verifySignature;
    }
    @Override
    protected String asyncService(Map<String, String> verifySignatureMap) {
        log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
        String paymentStatus = verifySignatureMap.get("paymentStatus");
        if (paymentStatus.equals("1")) {
            String orderNumber = verifySignatureMap.get("orderNumber");
            log.info(">>>>orderNumber:{orderNumber},已经支付成功 修改订单状态为已经支付...");
        }
        return resultSuccess();
    }
    @Override
    protected String resultSuccess() {
        return "success";
    }
    @Override
    protected String resultFail() {
        return "fail";
    }
}
登入後複製

工廠模式取得模版

public class TemplateFactory {
    private final static Map<String, AbstractPayCallbackTemplate> templateMap = new ConcurrentHashMap<>();
    static {
        templateMap.put("aliPay", new AliPayCallbackTemplate());
        templateMap.put("unionPay", new UnionPayCallbackTemplate());
    }
    public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
        AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) templateMap.get(templateId);
        return payCallbackTemplate;
    }
}
登入後複製

測試類別

public class Test {
    public static void main(String[] args) {
        AbstractPayCallbackTemplate aliPay = TemplateFactory.getPayCallbackTemplate("aliPay");
        String s = aliPay.asyncCallBack();
        System.out.println(s);
    }
}
登入後複製

以上是Java設計模式之模板方法實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板