古典的な設計モデルのテンプレート方法モデル【集約支払いプラットフォームはテンプレート+工場を使用して非同期コールバックを実現する】


1、テンプレート方法設計モードとは
        1.操作中のアルゴリズムのスケルトンを定義し、一部のステップの実装をサブクラスで完了します.テンプレートメソッドモードにより、サブクラスは、アルゴリズムの構造を変更することなく、アルゴリズムの特定のステップを再定義することができる.        2.テンプレートメソッドモードは、すべてのモードで最も一般的ないくつかのモードの1つであり、継承されたコード多重化に基づく基本技術であり、関連関係はありません.したがって,テンプレートメソッドモードのクラス構造図では,継承関係のみである.
2、テンプレート方法モデル設計の核心要点
AbstraactClass:抽象クラス、テンプレートメソッドを定義して実装します.このテンプレート法はアルゴリズムのスケルトンを定義し,論理の構成ステップは対応する抽象操作でサブクラスに遅延して実現する.ConcreteClass:親によって定義された1つ以上の抽象メソッドを実装します.
3、シーンを適用する
1、集約支払プラットフォームにおけるシステムコールバックコード再構築2、servlet要求の処理
4、非同期コールバック
プロセス
1、解析メッセージ(支払コールバック検証パラメータと検証署名)2、システムログへの書き込み3、解析メッセージが成功した場合、支払ステータスを正常に変更し、異なる支払結果を返す
maven依存
<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.0.1.RELEASEversion>
parent>
<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.16.10version>
    dependency>
    <dependency>
        <groupId>commons-langgroupId>
        <artifactId>commons-langartifactId>
        <version>2.6version>
    dependency>
dependencies>

テンプレートメソッド抽象クラス
/**
 * @Classname AbstractPayCallbackTemplate
 * @Description           
 * @Date 2019/5/16 11:17
 * @Created by mark
 */
@Slf4j
public abstract class AbstractPayCallbackTemplate {
    /**
     *          
     * @return
     */
    public final String asyncCallBack(){
        //1、         
        Map<String,String> verifySignature = verifySignature();
        //2、    
        payLog(verifySignature);
        //3、        
        String analysisCode = verifySignature.get("analysisCode");
        if(!StringUtils.equals(analysisCode, PayConstant.PAY_RESULT_SUCCESS)){
            return resultFail();
        }
        // 4、                 
        return asyncService(verifySignature);
    }

    /**
     *         
     * @return
     */
    protected abstract Map<String, String> verifySignature();

    /**
     *          
     *
     * @param verifySignature
     */
    @Async
    protected void payLog(Map<String, String> verifySignature){
        log.info(">>>         ....verifySignature:{}", verifySignature);
    }

    /**
     *       
     * @return
     */
    protected abstract String resultFail();

    /**
     *       
     * @return
     */
    protected abstract String resultSuccess();

    /**
     * (    )                      
     * @param verifySignature
     * @return
     */
    protected abstract String asyncService(Map<String, String> verifySignature);
}

実装クラス
1、AliPayCallbackTemplate
@Slf4j
@Component
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //          
        log.info(">>>            .....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1000");
        verifySignature.put("orderDes", "       ");
        //      1     ....
        verifySignature.put("aliPaymentStatus", PayConstant.PAY_STATUS_SUCCESS);
        verifySignature.put("aliPayOrderNumber", "ali_20190516");
        //          200    ..
        verifySignature.put("analysisCode", PayConstant.PAY_RESULT_SUCCESS);
        return verifySignature;
    }

    @Override
    protected String resultFail() {
        return PayConstant.PAY_ALI_FAIL;
    }

    @Override
    protected String asyncService(Map<String, String> verifySignature) {
        log.info(">>>          asyncService() verifySignatureMap:{}", verifySignature);
        String paymentStatus = verifySignature.get("aliPaymentStatus");
        if (PayConstant.PAY_STATUS_SUCCESS.equals(paymentStatus)) {
            String aliPayOrderNumber = verifySignature.get("aliPayOrderNumber");
            log.info(">>>>orderNumber:{}                  ...",aliPayOrderNumber);
        }
        return resultSuccess();
    }

    @Override
    protected String resultSuccess() {
        return PayConstant.PAY_ALI_SUCCESS;
    }
}

2、UnionPayCallbackTemplate
@Slf4j
@Component
public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //>>>>         >>>>>>>>
        log.info(">>>>>            .....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1000");
        verifySignature.put("orderDes", "      ");
        //      1     ....
        verifySignature.put("unionPaymentStatus", PayConstant.PAY_STATUS_SUCCESS);
        verifySignature.put("unionPayOrderNumber", "union_20190516");
        //          200    ..
        verifySignature.put("analysisCode", PayConstant.PAY_RESULT_SUCCESS);
        return verifySignature;
    }

    @Override
    protected String resultFail() {
        return PayConstant.PAY_UNION_FAIL;
    }

    @Override
    protected String resultSuccess() {
        return PayConstant.PAY_UNION_SUCCESS;
    }

    @Override
    protected String asyncService(Map<String, String> verifySignature) {
        log.info(">>>          asyncService() verifySignatureMap:{}", verifySignature);
        String paymentStatus = verifySignature.get("unionPaymentStatus");
        if (PayConstant.PAY_STATUS_SUCCESS.equals(paymentStatus)) {
            String unionPayOrderNumber = verifySignature.get("unionPayOrderNumber");
            log.info(">>>>orderNumber:{}                  ...",unionPayOrderNumber);
        }
        return resultSuccess();
    }
}

定数クラスの定義
PayConstant
public final class PayConstant {
    /**
     *     
     */
    public static final String PAY_RESULT_SUCCESS = "200";

    public static final String PAY_STATUS_SUCCESS = "1";

    public static final String PAY_ALI_SUCCESS = "SUCCESS";

    public static final String PAY_ALI_FAIL = "FAIL";

    public static final String PAY_UNION_SUCCESS = "OK";

    public static final String PAY_UNION_FAIL = "ERROR";
}

テンプレートを取得するファクトリモード
public class TemplateFactory {
    public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId){
        return SpringUtils.getBean(templateId,AbstractPayCallbackTemplate.class);
    }
}

ツールクラス
@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //  applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //  name   Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //  class  Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //  name,  Clazz     Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}

コンソール
@RestController
public class TemplateController {
    /**
     *     
     *
     * @return
     */
    @RequestMapping("/asyncCallBack")
    public String asyncCallBack(String templateId) {
        AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId);
        //                 
        return payCallbackTemplate.asyncCallBack();
    }
}

プログラムエントリ
@SpringBootApplication
@EnableAsync
public class TemplateApp {
    public static void main(String[] args) {
        SpringApplication.run(TemplateApp.class,args);
    }
}

出力結果:
アクセスaliPayCallbackアドレス:http://localhost:8080/asyncCallBack?templateId=aliPayCallbackTemplate
2019-05-20 15:23:14.311  INFO 9892 --- [nio-8080-exec-4] c.x.t.impl.AliPayCallbackTemplate        : >>>            .....verifySignature()
2019-05-20 15:23:14.311  INFO 9892 --- [nio-8080-exec-4] c.x.t.impl.AliPayCallbackTemplate        : >>>          asyncService() verifySignatureMap:{aliPayOrderNumber=ali_20190516, orderDes=       , price=1000, aliPaymentStatus=1, analysisCode=200}
2019-05-20 15:23:14.311  INFO 9892 --- [nio-8080-exec-4] c.x.t.impl.AliPayCallbackTemplate        : >>>>orderNumber:ali_20190516                  ...
2019-05-20 15:23:14.311  INFO 9892 --- [cTaskExecutor-2] c.x.t.AbstractPayCallbackTemplate        : >>>         ....verifySignature:{aliPayOrderNumber=ali_20190516, orderDes=       , price=1000, aliPaymentStatus=1, analysisCode=200}

unionPayCallbackアドレスへのアクセス:http://localhost:8080/asyncCallBack?templateId=unionPayCallbackTemplate
2019-05-20 15:25:24.031  INFO 9892 --- [nio-8080-exec-8] c.x.t.impl.UnionPayCallbackTemplate      : >>>>>            .....verifySignature()
2019-05-20 15:25:24.032  INFO 9892 --- [nio-8080-exec-8] c.x.t.impl.UnionPayCallbackTemplate      : >>>          asyncService() verifySignatureMap:{unionPayOrderNumber=union_20190516, orderDes=      , price=1000, unionPaymentStatus=1, analysisCode=200}
2019-05-20 15:25:24.032  INFO 9892 --- [nio-8080-exec-8] c.x.t.impl.UnionPayCallbackTemplate      : >>>>orderNumber:union_20190516                  ...
2019-05-20 15:25:24.032  INFO 9892 --- [cTaskExecutor-3] c.x.t.AbstractPayCallbackTemplate        : >>>         ....verifySignature:{unionPayOrderNumber=union_20190516, orderDes=      , price=1000, unionPaymentStatus=1, analysisCode=200}

5、テンプレート方法設計モードのメリットとデメリット
1)利点テンプレートメソッドモードは,不変の挙動をスーパークラスに移動することにより,サブクラスの重複コードを除去する.サブクラス実装アルゴリズムのいくつかの詳細は、アルゴリズムの拡張に役立ちます.親クラスが子クラスを呼び出して実装する操作により、子クラスの拡張によって新しい動作が追加され、「オープン-クローズの原則」に合致します.2)欠点各実装はサブクラスを定義する必要があり、これによりクラスの個数が増加し、設計がより抽象的になる.3.)適用シーンは,あるクラスのアルゴリズムで同じ手法を用いてコードを繰り返す.サブクラスの拡張を制御し、サブクラスはアルゴリズム規則を遵守しなければならない.