テンプレートモード
概念
- テンプレートパターン(テンプレートパターン)では、抽象クラスがそのメソッドの方法/テンプレートを公に定義します。そのサブクラスは、必要に応じてメソッドをオーバーライドすることで実装できますが、呼び出しは抽象クラスで定義された方法で行われます。このタイプのデザインパターンは、戦略パターンや責任の連鎖パターンと同様に、データ動作パターンです。
- テンプレートモードは、ビジネスモデルに従ってプログラムの操作アルゴリズムスケルトンを定義することと同等であり、いくつかのステップの実装はサブクラスで完了します。テンプレートメソッドパターンを使用すると、サブクラスは、アルゴリズムの構造を変更せずに、アルゴリズムの特定のステップを再定義できます。
特徴
- キーコードは抽象クラスに実装され、他のステップはサブクラスに実装されます。
- AbstractClass:抽象クラス。テンプレートメソッドを定義および実装します。このテンプレートメソッドはアルゴリズムのスケルトンを定義し、論理合成ステップは対応する抽象操作のサブクラス実装に延期されます。
- サブクラス:親クラスの1つ以上の抽象メソッドを実装できます。
使用するシーン
最も一般的なのは一括支払いです。支払いプラットフォームが異なればコールバックインターフェイスも異なりますが、処理の一般的なプロセスは同じです。したがって、一般的なアルゴリズムスケルトンは親クラス(抽象クラス)で定義でき、特定のものはによって実装できます。サブクラス。
長所と短所
- 利点:
- 定数部分をカプセル化し、可変部分を展開します。
- 保守が容易な共通コードを抽出します。
- 動作は親クラスによって制御され、サブクラスによって実装されます。
- 短所:
実装ごとにサブクラスを実装する必要があります。これにより、きめ細かいオブジェクトが増加し、システムが大きくなります。
パターンの構造
この記事では、AlipayとWeChatのコールバックで使用されるシナリオを紹介します。
図(インターネットからの写真)を参照してください。
開発ステップ
- 抽象クラスを作成します。これは主にアルゴリズムスケルトンの定義を担当し、プロセス全体の方向性を担当し、サブクラスが独自のビジネス特性に従って実装する抽象メソッドを提供します。
package com.lee.template.service;
import java.util.Map;
/**
* @author zfl_a
* @Desc 描述各个支付平台回调处理大致流程。验证签名(不同),日志收集(相同),验证签名状态(相同),根据不同支付结果更新状态(不同)
* @date 2020/8/12
* @project springboot_design_pattern
*/
public abstract class AbstractPayCallbackTemplate {
/**
* 定义算法骨架。按照此流程执行相关操作
* @return
*/
public String asynCallBack() {
// 验证签名(不同)
Map<String,String> verifySignature = verifySignature();
// 日志收集(相同)
payLog(verifySignature);
// 验证签名状态(相同)
String code = verifySignature.get("code");
if(!"200".equals(code)) {
return fail();
}
// 根据不同支付结果更新状态(不同)
return asyncPayResult(verifySignature);
}
/**
* 失败结果
* @return
*/
protected abstract String fail();
/**
* 成功结果
* @return
*/
protected abstract String success();
/**
* 根据不同状态同步支付状态到数据库
* @param verifySignature
* @return
*/
protected abstract String asyncPayResult(Map<String, String> verifySignature);
/**
* 日志收集
* @param verifySignature
*/
protected abstract void payLog(Map<String, String> verifySignature);
/**
* 获取并验证签名
* @return
*/
protected abstract Map<String, String> verifySignature() ;
}
-
親クラスによって抽象化されたメソッドを実装するための具体的な実装クラスを作成します。
Ali-Payで支払う
package com.lee.template.service.impl;
import com.lee.template.service.AbstractPayCallbackTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @author zfl_a
* @date 2020/8/12
* @project springboot_design_pattern
*/
@Service
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
@Override
protected String fail() {
return "支付宝支付失败";
}
@Override
protected String success() {
return "支付宝支付成功";
}
@Override
protected String asyncPayResult(Map<String, String> verifySignature) {
System.out.println("【支付宝支付】根据支付状态结果同步至数据库");
//支付状态 1代表支付成功
String payStatus = verifySignature.get("payStatus");
if("1".equals(payStatus)) {
//订单编号
String orderNumber = verifySignature.get("orderNumber");
System.out.println("【支付宝支付】支付成功,状态已修改,订单编号为:"+orderNumber);
}
return success();
}
@Override
protected void payLog(Map<String, String> verifySignature) {
System.out.println("【支付宝支付】记录操作日志....."+verifySignature);
}
@Override
protected Map<String, String> verifySignature() {
Map<String,String> verifySignature = new HashMap<>();
verifySignature.put("code","200");
//1表示成功
verifySignature.put("payStatus","1");
verifySignature.put("orderNumber","202008120002");
verifySignature.put("price","3999");
verifySignature.put("desc","一加 8");
return verifySignature;
}
}
WeChat Pay
package com.lee.template.service.impl;
import com.lee.template.service.AbstractPayCallbackTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @author zfl_a
* @date 2020/8/12
* @project springboot_design_pattern
*/
@Service
public class WxPayCallbackTemplate extends AbstractPayCallbackTemplate {
@Override
protected String fail() {
return "微信支付失败";
}
@Override
protected String success() {
return "微信支付成功";
}
@Override
protected String asyncPayResult(Map<String, String> verifySignature) {
System.out.println("【微信支付】根据支付状态结果同步至数据库");
//支付状态 1代表支付成功
String payStatus = verifySignature.get("payStatus");
if("1".equals(payStatus)) {
//订单编号
String orderNumber = verifySignature.get("orderNumber");
System.out.println("【微信支付】支付成功,状态已修改,订单编号为:"+orderNumber);
}
return success();
}
@Override
protected void payLog(Map<String, String> verifySignature) {
System.out.println("【微信支付】记录操作日志...."+verifySignature);
}
@Override
protected Map<String, String> verifySignature() {
Map<String,String> verifySignature = new HashMap<>();
verifySignature.put("code","200");
//1表示成功
verifySignature.put("payStatus","1");
verifySignature.put("orderNumber","202008120001");
verifySignature.put("price","3699");
verifySignature.put("desc","华为 Nova7 Pro");
return verifySignature;
}
}
- テンプレートファクトリを作成して、呼び出し元がさまざまなテンプレートIDに従ってさまざまなプロセスを実行できるようにします。
package com.lee.template.factory;
import com.lee.template.service.AbstractPayCallbackTemplate;
import com.lee.utils.SpringUtils;
/**
* @author zfl_a
* @date 2020/8/12
* @project springboot_design_pattern
*/
public class TemplateFactory {
public static AbstractPayCallbackTemplate findCallBackTemplate(String templateId){
AbstractPayCallbackTemplate abstractPayCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId);
return abstractPayCallbackTemplate ;
}
}
- テストクラスを作成する
package com.lee.template.controller;
import com.lee.template.factory.TemplateFactory;
import com.lee.template.service.AbstractPayCallbackTemplate;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zfl_a
* @date 2020/8/12
* @project springboot_design_pattern
*/
@RestController
@RequestMapping("/template")
public class TemplateController {
/**
* 回调
* @param templateId
* @return
*/
@GetMapping("/aysnCallBack")
public String aysnCallBack(String templateId){
if(StringUtils.isBlank(templateId)) {
return "请传递支付模板id";
}
//从工厂中根据模板ID取出对应的模板
AbstractPayCallbackTemplate callBackTemplate = TemplateFactory.findCallBackTemplate(templateId);
return callBackTemplate.asynCallBack();
}
}
テスト結果は次のとおりです。
-
Alipay支払いテンプレートID、?templateId = aliPayCallbackTemplateを渡します
-
WeChat支払いテンプレートIDを渡しますか?templateId = wxPayCallbackTemplate
デザインパターンに関するすべてのコードはホストされます:デザインパターンコード、注意を払うことを歓迎します。みんなで成長したい!