likes
comments
collection
share

采用策略模式实现订单支付多种方式

作者站长头像
站长
· 阅读数 15

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

背景

项目中订单支付为常见的功能,一般的订单支付都会包含多种方式,例如聚合支付、会员支付、积分支付的等多种方式,如果采用传统的方式来实现,需要使用多个if/else条件判断,本文将介绍如何采用策略+工厂模式实现多种方式的订单支付问题。

简介

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。

基本原理

采用策略模式实现订单支付多种方式

基本元素组成如下:

  • 环境 (Context):持有一个策略类的引用,最终给客户端调用。
  • 抽象策略 (Strategy): 策略类,通常是一个接口或者抽象类。
  • 具体策略 (ConcreteStrategy):实现了策略类中的策略方法,封装相关的算法和行为。

具体实现

定义抽象策略

public interface PayWayService
{
    Result pay(WxPayObject wxpayObject);
}

说明:定义抽象支付接口。

具体策略

微信支付

@Component("wx")
public class WxPayWayServiceImpl implements PayWayService
{
    private Logger logger = 
            LoggerFactory.getLogger(WxPayWayServiceImpl.class);
    
    @Override
    public Result pay(WxPayObject wxPayObject)
    {
        logger.info("this is wx pay way");
        return Result.success(wxPayObject);
    }
}

说明:注意@Component注解需要写入别名。

支付宝支付

@Component("zfb")
public class ZfbPayWayServiceImpl implements PayWayService
{
    private Logger logger = 
            LoggerFactory.getLogger(ZfbPayWayServiceImpl.class);
    
    @Override
    public Result pay(WxPayObject wxpayObject)
    {
        logger.info("this is zfb pay way");
        return Result.success(wxpayObject);
    }
}

会员支付

@Component("member")
public class MemberPayWayServiceImpl implements PayWayService
{
    private Logger logger = 
            LoggerFactory.getLogger(MemberPayWayServiceImpl.class);
    
    @Override
    public Result pay(WxPayObject wxpayObject)
    {
        logger.info("this is member pay way");
        return Result.success(wxpayObject);
    }
}

工厂类

@Component
public class PayWayFactory
{
    @Autowired
    private Map<String, PayWayService> paywayServiceMap;
    
    public PayWayService getPayWayService(String type) 
    {
        PayWayService payWayService = paywayServiceMap.get(type);
        if(payWayService==null)
        {
            throw new RuntimeException("未指定的支付类型");
        }
        return payWayService;
    }
}

说明:通过工厂类获取具体的策略实现。

  private Map<String, PayWayService> paywayServiceMap

@Autowired 标注作用于Map类型时,如果Map的key为String类型,则Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 iD 或 name 作为Map的key。

测试

@RestController
public class TestController
{
    @Autowired
    private PayWayFactory payWayFactory;
    
    @RequestMapping("/getPayWay")
    public void getPayWay(@RequestParam String payWay)
    {
        WxPayObject wxpayObject =new WxPayObject();
        payWayFactory.getPayWayService(payWay).pay(wxpayObject);
    }
}

输入 payway分别输入wx和member输出结果如下:

采用策略模式实现订单支付多种方式

策略模式优缺点

优点

  • 提供了管理相关的算法族的办法,从而避免重复的代码。
  • 提供了可以替换继承关系的办法。因为继承使得动态改变算法或行为变得不可能。
  • 可以避免使用多重条件转移语句。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。

总结

本文对策略模式进行了讲解,策略模式在实际开发过程中应用的比较广泛,所以大家还是需要熟练的掌握其用法,如有疑问,请随时反馈。