どのように賢い春ブートプロジェクトにおける戦略パターンを使用し、他の場合を取り除くために!

ストレート対象に

我々は、すべてのデザインパターン(デザインパターン)前任者は、コード開発の経験をまとめたものであることを知って、特定の一連のルーチンの問題を解決することです。これは、構文は定義されていないが、解の集合は、コードの再利用性、保守性、可読性、堅牢性とセキュリティを向上させるために使用することができます。
さて、私たちは、デザインパターンを知るために必要がある場合がありますが、どのようにプロジェクトに使用されるが、まだ少し混乱することができ、今日、同社はちょうど私がデザインパターンを使用できるようにするシーンをプロジェクト:Strategyパターンを。

シーン

その上アリペイ、マイクロチャネル、CUP、財布(APP個々の口座残高)と:プリペイド顧客の注文(同じ理由を支払うために発注)については、私たちは皆知っている、今日の支払いは、例えば、非常に多くあります。
クエリエンティティクエリ:

/**
 * @author Howinfun
 * @desc 查询
 * @date 2019/10/22
 */
@Data
public class ChargeQuery {
    
    /** 支付方式(ALI/WX/UNION) */
    @NotBlank(message = "支付方式不能为空",groups = PayWayNotBlank.class)
    private String payWay;
    
    /** 充值金额 */
    @NotNull(message = "充值金额不能为空",groups = AmountNotNull.class)
    private Double amount;
}

サービスインタフェース:

/**
 * @author Howinfun
 * @desc 充电-充值模块
 * @date 2019/10/30
 */
public interface ChargeRechargeService {

    /**
     * 根据不用支付方式进行用户余额充值
     * @param query
     * @return
     */
    Result recharge(ChargeQuery query);

    /**
     * 充值回调
     * @param rechargeCallBack
     */
    Result rechargeCallBack(RechargeCallBack rechargeCallBack);
}

伝統的なやり方

条件付きまたはスイッチを次のように使用している他の場合:

/**
 * @author Howinfun
 * @desc
 * @date 2019/10/30
 */
@Service
@AllArgsConstructor
@Slf4j
public class ChargeRechargeServiceImpl implements ChargeRechargeService {

    private final CarUserMapper carUserMapper;
    private final IncomePaymentMapper incomePaymentMapper;
    private final RechargeRecordMapper rechargeRecordMapper;
    private final PayWayHandlerContext payWayHandlerContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result recharge(ChargeQuery query) {
        Result result = new Result();
        // ......
        // ......
        if (PayConstant.PAY_WAY_WX.equals(query.getPayWay())){
            // 微信
            // ......
        }else if (PayConstant.PAY_WAY_ALI.equals(query.getPayWay())){
            // 支付宝
            // ......

        }else if (PayConstant.PAY_WAY_UNION_PAY.equals(query.getPayWay())){
             // 银联
             // ......
    
        }
        return result;
    }
}

概要:私たちは、伝統的な実装は非常に面倒であることがわかりますし、コードは非常に単純な、貧しい人々スケーラビリティではありません。我々は新しい支払い方法をアクセスする場合は、次に我々は場合にのみ、それ以外の追加していくことができます。

戦略モード

話は私のコードを表示し、安いです 。
あなたは戦略パターンを使用している場合我々は、見て、サービスコードが鋸になります。

/**
 * @author Howinfun
 * @desc
 * @date 2019/10/30
 */
@Service
@AllArgsConstructor
@Slf4j
public class ChargeRechargeServiceImpl implements ChargeRechargeService {

    private final PayWayHandlerContext payWayHandlerContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result recharge(ChargeQuery query) {
        return this.payWayHandlerContext.getHandlerInstance(query.getPayWay()).handler(query);
    }
}

emmmm、本当にずっと簡単。以下のコード、そして簡潔な、とserviceImplコードを変更するための新しい支払方法ので、もはや心配しないだけで。

以下の詳細な説明:
1、すべての最初は、私達は支払プロセッサに対応したタイプを識別するためにノートをカスタマイズする必要があります。

/**
 * @author Howinfun
 * @desc 自定义注解,标识支付类型
 * @date 2019/11/2
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface PayWayHandler {

    String value();
}

2.次に、抽象プロセッサ、各支払いを継承この抽象プロセッサのプロセッサ、handleメソッドを実装します。

/**
 * @author Howinfun
 * @desc 抽象订单类型处理器
 * @date 2019/11/2
 */
public abstract class AbstractPayWayHandler {

    /**
     *
     * @param query
     * @return
     */
    abstract public Result handler(ChargeQuery query);
}

図3に示すように、そのようなAlipayの、微信CUPとして実装クラスは、:
注:各プロセッサは、Spring管理に、@Componentを追加しなければなりません。

/**
 * @author Howinfun
 * @desc 支付宝支付
 * @date 2019/11/2
 */
@Component
@PayWayHandler("ALI")
@Slf4j
@AllArgsConstructor
public class AliPayWayHandler extends AbstractPayWayHandler {
    
    // ....各种依赖

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

/**
 * @author Howinfun
 * @desc 微信支付
 * @date 2019/11/2
 */
@Component
@PayWayHandler("WX")
@Slf4j
@AllArgsConstructor
public class WxPayWayHandler extends AbstractPayWayHandler {
    
    // ....各种依赖

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

/**
 * @author Howinfun
 * @desc 银联支付
 * @date 2019/11/2
 */
@Component
@PayWayHandler("UNION")
@Slf4j
@AllArgsConstructor
public class UnionPayWayHandler extends AbstractPayWayHandler {
    
    // ....各种依赖

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

4、その後は最も集中、インタフェースApplicationContextAwareを実装するクラスを作成し、書き換えsetApplicationContext方法を来て、その後、豆のカスタム注釈@PayWayHandler、その後、保存され、簡単にアクセスできるサービスをスキャンします。

/**
 * @author Howinfun
 * @desc
 * @date 2019/11/2
 */
@Component
public class PayWayHandlerContext implements ApplicationContextAware {

    @Autowired ApplicationContext applicationContext;

    /** key为PayWay,value为class*/
    private static final Map<String,Class> handlerMap = new HashMap<>(10);

    public AbstractPayWayHandler getHandlerInstance(String payType){
        Class clazz = handlerMap.get(payType);
        if (clazz == null){
            throw new CustomDeniedException("暂不支持此支付方式");
        }
        return (AbstractPayWayHandler) applicationContext.getBean(clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 遍历带有PayTypeHandler注释的类
        Map<String,Object> beans = applicationContext.getBeansWithAnnotation(PayWayHandler.class);
        if (beans != null && beans.size() > 0) {
            for (Object serviceBean : beans.values()) {
                String payType = serviceBean.getClass().getAnnotation(PayWayHandler.class).value();
                handlerMap.put(payType, serviceBean.getClass());
            }
        }
    }
}

要約:この、ServiceImplハンドラが処理payWay上の対応する伝送の前端に応じて選択することができます。私は、戦略パターンが他のコード、およびスケーラビリティが大幅に改善されている場合は、もはや新しい支払方法ので心配ないとビジネスのコードを変更複合体を簡素化します。

おすすめ

転載: www.cnblogs.com/Howinfun/p/11785460.html