ホームページ  >  記事  >  Java  >  Java デザイン パターン テンプレート メソッドの例の分析

Java デザイン パターン テンプレート メソッドの例の分析

WBOY
WBOY転載
2023-05-14 14:43:061179ブラウズ

コンセプト

テンプレートメソッドパターンは、全パターンの中で最も一般的なパターンの一つであり、継承によるコード再利用の基礎技術であり相関関係はありません。したがって、テンプレートメソッドパターンのクラス構成図には継承関係のみが存在します。

コア設計ポイント

AbstractClass: 抽象クラス。テンプレート メソッドを定義および実装します。このテンプレート メソッドはアルゴリズムのスケルトンを定義し、論理構成ステップは対応する抽象操作のサブクラスに延期されます。

ConcreteClass: 親クラスによって定義された 1 つ以上の抽象メソッドを実装します。

メリットとデメリット

メリット

  • テンプレート メソッドを使用して、同じ処理ロジックのコードを抽象親クラスに配置すると、再利用性が向上します。コードの 。

  • さまざまなコードをさまざまなサブクラスに配置し、サブクラスの拡張を通じて新しい動作を追加して、コードのスケーラビリティを向上させます。

  • 変更されていない動作を親クラスに記述し、サブクラスの重複コードを削除して、開始と終了の原則に準拠した優れたコード再利用プラットフォームを提供します。

欠点

クラスの数が増えると、各抽象クラスを実装するためのサブクラスが必要になり、その結果、クラスの数が増加し、複雑さが増加します。 。クラス数の増加は、間接的にシステム実装の複雑さを増加させます。継承関係には独自の欠点があり、親クラスが新しい抽象メソッドを追加すると、すべてのサブクラスでそれを変更する必要があります。

#アプリケーション シナリオ

  • 親クラスの観点: アルゴリズムの変更されていない部分を一度に実装し、可変部分は実装のためにサブクラスに任せます;

  • サブクラスの観点: コードの重複を避けるために、各サブクラスで共通部分が抽出され、共通の親クラスに集約されます。

テンプレート メソッド パターンの目的は次のとおりです。サブクラスが固定メソッドの特定のステップを拡張または具体的に実装できるようにします。テンプレートの場合、それは固定アルゴリズムのセットであり、固定アルゴリズム内の特定のアルゴリズム ステップはサブクラスを通じて拡張できます。

テンプレート メソッドとストラテジ パターンの違い

ストラテジ パターンはアルゴリズムのカプセル化です。一連のアルゴリズムを対応するクラスにカプセル化し、これらのクラスは同じインターフェイスを実装し、それぞれのクラスと対話します。その他の交換可能です。アルゴリズムのカプセル化に焦点を当てた別のパターン

# もありますが、これはテンプレート メソッド パターンです。クラス図を比較すると、ストラテジ パターンとテンプレート メソッド パターンの違いは、次の追加のみであることがわかります。別のカプセル化クラス

Context、テンプレート メソッド パターンとの違いは、テンプレート メソッド パターンでは呼び出しアルゴリズムの本体が抽象親クラスにあるのに対し、ストラテジ パターンでは呼び出しアルゴリズムの本体が抽象親クラスにあることです。呼び出しアルゴリズムの本体はカプセル化されている カプセル化されたクラス Context に関して言えば、抽象戦略 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;
    }
}

テストクラス

りー

以上がJava デザイン パターン テンプレート メソッドの例の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。