100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 设计模式之策略+工厂实现支付功能代码优化

设计模式之策略+工厂实现支付功能代码优化

时间:2021-06-10 11:05:34

相关推荐

设计模式之策略+工厂实现支付功能代码优化

源码地址:支付设计模式优化

背景

在我们开发中支付功能可能遇到的不少,今天这个案例就是以支付为中心,通过结合设计模式实现支付功能的扩展性。方便我们以后需求增加、变更的时候是我们开发起来得心应手,同时也减少QA的回归时间。

设计关系图

实现类

接口基类

/*** @ClassName IPay* @Description 支付接口* @Author xiaowu* @Date /8/10 6:02 下午*/public interface IPayStrategy<T> {/*** 支付* @param payBusiness* @return* @throws Exception*/Result pay(PayBusiness<T> payBusiness) throws Exception;Logger logger = Logger.getLogger(IPayStrategy.class.getName());}

策略控制类

/**** @ClassName ContextHandler* @Description: 策略控制* @Author xiaowu* @Date /8/10* @Version V1.0**/public class ContextStrategy<T> {private IPayStrategy<T> pay;public ContextStrategy(IPayStrategy<T> pay) {this.pay = pay;}public Result payProcess(PayBusiness<T> t) throws Exception {return pay.pay(t);}}

工厂类

通过init 方法加载实现类的class 路径,注册实现到本地缓冲中,方便策略控制类获取具体实现类对象。

/*** @ClassName PayStrategyFactory* @Description: 支付策略工厂类* @Author 小五* @Date /8/10* @Version V1.0**/public class PayStrategyFactory {private Logger logger = Logger.getLogger(PayFactoryInstance.class);private static Map<String, IPayStrategy> registerServices = new ConcurrentHashMap<String, IPayStrategy>();private PayStrategyFactory() {init();}public static PayStrategyFactory getInstance() {return PayFactoryInstance.instance;}private static class PayFactoryInstance {private static PayStrategyFactory instance = new PayStrategyFactory();}private void init() {Set<Class<?>> classes = ClassScanner.scanPackage("com.bj.drj.design01.factory.impl");classes.stream().forEach(x -> registerService(x));}private void registerService(Class registerClass) {try {registerServices.put(registerClass.getName(), (IPayStrategy) registerClass.newInstance());} catch (Exception e) {logger.error(e);}}public IPayStrategy getPayService(String payCode) {return registerServices.get(PayEnum.getClassPath(payCode));}}

支付方式枚举

/*** @ClassName PayEnum* @Description 支付方式枚举* @Author drj* @Date /8/11 2:14 下午*/public enum PayEnum {ALI_PAY("ali", "com.bj.drj.design01.factory.impl.AliPay"),QQ_PAY("qq", "com.bj.drj.design01.factory.impl.QqPay"),WX_PAY("wx", "com.bj.drj.design01.factory.impl.WxPay");private String payCode;private String payClassPath;public String getPayCode() {return payCode;}public String getPayClassPath() {return payClassPath;}PayEnum(String payCode, String payClassPath) {this.payCode = payCode;this.payClassPath = payClassPath;}public static String getClassPath(String payCode) {for (PayEnum payEnum : values()) {if (Objects.equals(payEnum.getPayCode(), payCode)) {return payEnum.getPayClassPath();}}return null;}}

支付实现类(aliPay)

这里只写模拟阿里支付宝实现类,其他类似

public class AliPay implements IPayStrategy<AliPayRequest> {/*** @param payBusiness* @return* @throws Exception*/@Overridepublic Result<AliPayResponse> pay(PayBusiness<AliPayRequest> payBusiness) throws Exception {AliPayRequest aliPayRequest = new AliPayRequest();aliPayRequest.setAli("阿里云");payBusiness.setBody(aliPayRequest);IPayStrategy.logger.info("Ali Pay 请求参数: " + JSON.toJSONString(payBusiness));Result<AliPayResponse> responseResult = new Result<>();responseResult.setResultCode(200);responseResult.setResultMsg("调用成功!");AliPayResponse aliPayResponse = new AliPayResponse();aliPayResponse.setAliPayResult("aliPay 接口调用成功 等待回调");responseResult.setResultData(aliPayResponse);return responseResult;}}

服务调用

/*** @ClassName PayBusiness* @Description: TODO* @Author drj* @Date /8/10* @Version V1.0**/public class PayBusiness<T> {/*** 支付金額*/private BigDecimal payAccount;/*** 支付方式*/private String payName;/*** 支付方式code*/private String payCode;/*** 不同支付方式业务参数*/private T body;public BigDecimal getPayAccount() {return payAccount;}public void setPayAccount(BigDecimal payAccount) {this.payAccount = payAccount;}public String getPayName() {return payName;}public void setPayName(String payName) {this.payName = payName;}public T getBody() {return body;}public void setBody(T body) {this.body = body;}public String getPayCode() {return payCode;}public void setPayCode(String payCode) {this.payCode = payCode;}}

public class PayService {public Result pay(PayBusiness payBusiness) throws Exception {ContextStrategy contextHandler = new ContextStrategy(PayStrategyFactory.getInstance().getPayService(payBusiness.getPayCode()));return contextHandler.payProcess(payBusiness);}}

从上面服务调用可以发现我们只需要传入请求参数两行代码实现service 层的调用。后面我们假如有新需求增加其他支付方式,比如:qq、wx 只需要增加枚举和对应的实现类,即可 很容易得到扩展。

请求参数和返回参数分别都使用泛型接受可变对象,使得我们更加灵活。

测试

public class PayTest {@Injectprivate PayService payService;@Injectprivate PayDemo payDemo;@Beforepublic void init() {CommonInjector.getInjector().injectMembers(this);}@Testpublic void testWxPay() throws Exception {PayBusiness payBusiness = new PayBusiness();payBusiness.setPayAccount(new BigDecimal(200));payBusiness.setPayCode("wx");payBusiness.setPayName("微信");Result pay = payService.pay(payBusiness);System.out.printf("支付接口返回参数:" + JSON.toJSONString(pay));}@Testpublic void testAliPay() throws Exception {PayBusiness payBusiness = new PayBusiness();payBusiness.setPayAccount(new BigDecimal(200));payBusiness.setPayCode("ali");payBusiness.setPayName("阿里");Result pay = payService.pay(payBusiness);System.out.printf("支付接口返回参数:" + JSON.toJSONString(pay));}@Testpublic void testPay() throws Exception {PayBusiness payBusiness = new PayBusiness();payBusiness.setPayAccount(new BigDecimal(200));payBusiness.setPayCode("qq");payBusiness.setPayName("qq 钱包");Result payQq = payService.pay(payBusiness);System.out.println("支付接口返回参数:" + JSON.toJSONString(payQq));payBusiness.setPayCode("wx");payBusiness.setPayName("wx 支付");Result<WxPayResponse> payWx = payService.pay(payBusiness);System.out.println("支付接口返回参数:" + JSON.toJSONString(payWx));payBusiness.setPayCode("ali");payBusiness.setPayName("ali 支付");Result<AliPayResponse> payAli = payService.pay(payBusiness);System.out.println("支付接口返回参数:" + JSON.toJSONString(payAli));}

九月 28, 11:42:59 下午 com.bj.drj.design01.factory.impl.QqPay pay

信息: QPay 请求参数: {“body”:{“qq”:“qq”},“payAccount”:200,“payCode”:“qq”,“payName”:“qq 钱包”}

九月 28, 11:42:59 下午 com.bj.drj.design01.factory.impl.QqPay pay

信息: 调用qq支付

支付接口返回参数:{“resultCode”:200,“resultData”:{“qqPayResult”:“qqPay 接口调用成功 等待回调”},“resultMsg”:“调用成功!”}

支付接口返回参数:{“resultCode”:200,“resultData”:{“wxPayResult”:“wx Pay 接口调用成功, 等待回调”},“resultMsg”:“调用成功!”}

九月 28, 11:42:59 下午 com.bj.drj.design01.factory.impl.WxPay pay

支付接口返回参数:{“resultCode”:200,“resultData”:{“aliPayResult”:“aliPay 接口调用成功 等待回调”},“resultMsg”:“调用成功!”}

信息: Wx Pay 请求参数: {“body”:{“wx”:“微信”},“payAccount”:200,“payCode”:“wx”,“payName”:“wx 支付”}

九月 28, 11:42:59 下午 com.bj.drj.design01.factory.impl.AliPay pay

信息: Ali Pay 请求参数: {“body”:{“ali”:“阿里云”},“payAccount”:200,“payCode”:“ali”,“payName”:“ali 支付”}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。