(設計モード特集3)テンプレートメソッドモード

18009 ワード

テンプレート方法とは
1.操作中のアルゴリズムのスケルトンを定義し、一部のステップの実装をサブクラスで完了します.
テンプレートメソッドモードにより、サブクラスは、アルゴリズムの構造を変更することなく、アルゴリズムの特定のステップを再定義することができる.
2.テンプレートメソッドモードは、すべてのモードで最も一般的ないくつかのモードの1つであり、継承されたコード多重化に基づく基本技術であり、関連関係はない.したがって,テンプレートメソッドモードのクラス構造図では,継承関係のみである.
 
コア設計のポイント:
AbstraactClass:抽象クラス、テンプレートメソッドを定義して実装します.このテンプレート法はアルゴリズムのスケルトンを定義し,論理的構成ステップは対応する抽象操作においてサブクラスに遅延して実現する.
ConcreteClass:親クラスが定義した1つ以上の抽象メソッドを実装します.
 
テンプレートメソッドシーンの適用
 
  • 例えば、集約支払プラットフォームにおけるシステムコールバックコード再構成
  • サーブレット要求
  •  
     
    テンプレートメソッド抽象クラス
     
     1 @Slf4j
     2 @Component
     3 public abstract class AbstractPayCallbackTemplate {
     4 
     5     /**
     6      *       
     7      *
     8      * @return
     9      */
    10     public String asyncCallBack() {
    11         // 1.         
    12         Map verifySignatureMap = verifySignature();
    13         // 2.       ,     ..
    14         payLog(verifySignatureMap);
    15         String analysisCode = verifySignatureMap.get("analysisCode");
    16         if (!analysisCode.equals("200")) {
    17             return resultFail();
    18         }
    19         // 3.           
    20         return asyncService(verifySignatureMap);
    21 
    22     }
    23 
    24 
    25     /**
    26      *         
    27      *
    28      * @return
    29      */
    30     protected abstract Map verifySignature();
    31 
    32     /**
    33      *            
    34      *
    35      * @param verifySignatureMap
    36      */
    37     @Async
    38     private void payLog(Map verifySignatureMap) {
    39         log.info(">>>>>>>>>>      payLog........");
    40     }
    41 
    42     /**
    43      *                  
    44      *
    45      * @return
    46      */
    47     protected abstract String asyncService(Map verifySignatureMap);
    48 
    49     /**
    50      *       ..
    51      *
    52      * @return
    53      */
    54     protected abstract String resultSuccess();
    55 
    56     /**
    57      *       
    58      *
    59      * @return
    60      */
    61     protected abstract String resultFail();
    62 }

     
    具体的な実装テンプレート
    アリペイコール偽コード
     
     1 @Component
     2 @Slf4j
     3 public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
     4     @Override
     5     protected Map verifySignature() {
     6         //>>>>           >>>>>>>>>>>>>>>>
     7         log.info(">>>>>            .....verifySignature()");
     8         Map verifySignature = new HashMap<>();
     9         verifySignature.put("price", "1399");
    10         verifySignature.put("orderDes", "  CC       ");
    11         //      1     ....
    12         verifySignature.put("aliPayMentStatus", "1");
    13         verifySignature.put("aliPayOrderNumber", "201910101011");
    14         //          200    ..
    15         verifySignature.put("analysisCode", "200");
    16         return verifySignature;
    17     }
    18 
    19     @Override
    20     protected String asyncService(Map verifySignatureMap) {
    21         log.info(">>>>>   asyncService()verifySignatureMap:{}", verifySignatureMap);
    22         String paymentStatus = verifySignatureMap.get("aliPayMentStatus");
    23         if (paymentStatus.equals("1")) {
    24             String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber");
    25             log.info(">>>>orderNumber:{aliPayOrderNumber},                  ...");
    26         }
    27         return resultSuccess();
    28     }
    29 
    30     @Override
    31     protected String resultSuccess() {
    32         return "ok";
    33     }
    34 }

     
    銀聯支払コールバック偽コード
     1 @Component
     2 @Slf4j
     3 public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
     4     @Override
     5     protected Map verifySignature() {
     6         //>>>>           >>>>>>>>>>>>>>>>
     7         log.info(">>>>>            .....verifySignature()");
     8         Map verifySignature = new HashMap<>();
     9         verifySignature.put("price", "1399");
    10         verifySignature.put("orderDes", "  CC       ");
    11         //      1     ....
    12         verifySignature.put("paymentStatus", "1");
    13         verifySignature.put("orderNumber", "201910101011");
    14         //          200    ..
    15         verifySignature.put("analysisCode", "200");
    16         return verifySignature;
    17     }
    18 
    19     @Override
    20     protected String asyncService(Map verifySignatureMap) {
    21         log.info(">>>>>   asyncService()verifySignatureMap:{}", verifySignatureMap);
    22         String paymentStatus = verifySignatureMap.get("paymentStatus");
    23         if (paymentStatus.equals("1")) {
    24             String orderNumber = verifySignatureMap.get("orderNumber");
    25             log.info(">>>>orderNumber:{orderNumber},                  ...");
    26         }
    27         return resultSuccess();
    28     }
    29 
    30     @Override
    31     protected String resultSuccess() {
    32         return "success";
    33     }
    34 }

    ファクトリモード取得テンプレート
     
    1 public class TemplateFactory {
    2 
    3     public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
    4         AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId);
    5         return payCallbackTemplate;
    6     }
    7 }

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