策略模式

1. 定义

定义一系列算法,把他们一个个封装起来,并且使他们可以互相替换。本模式使得算法
可以独立于使用它的客户而变化。

2. 策略模式的结构

策略模式结构图

  • Strategy : 策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法
  • ConcreteStrategy:具体的策略实现,也就是具体的算法实现。
  • Context:上下文,负责和具体具体的策略类交互。

3. 本质

分离算法,选择实现

4. 实例

下面以订单支付支付为场景为例来演示策略模式:网上买东西订单支付一般会选择支付宝支付,微信支付,银联支付等等支付方式来实现。如果我们要实现这个功能其实很简单。下面给出不采用设计模式的实现:

Payment

/**
 * 支付 的策略接口
 * @author lijun
 * @since 2018-03-16 13:48
 */
public interface Payment {
    /**
     * 支付接口
     * @param userId 用户ID
     * @param amount 支付金额
     * @return PayState 支付状态
     */
    PayState pay(String userId,double amount);
}

AliPay

/**
 * 支付宝支付
 * @author lijun
 * @since 2018-03-16 13:57
 */
public class AliPay implements Payment {
    /**
     * 支付接口
     *
     * @param userId 用户ID
     * @param amount 支付金额
     * @return PayState 支付状态
     */
    @Override
    public PayState pay(String userId, double amount) {
        System.out.println("欢迎使用支付宝");
        System.out.println("查询账户余额,开始扣款");
        return new PayState(200,"支付成功",amount);
    }
}

WechatPay

/**
 * 微信支付
 * @author lijun
 * @since 2018-03-16 14:02
 */
public class WechatPay implements Payment {
    /**
     * 支付接口
     *
     * @param userId 用户ID
     * @param amount 支付金额
     * @return PayState 支付状态
     */
    @Override
    public PayState pay(String userId, double amount) {
        System.out.println("欢迎使用微信支付");
        System.out.println("直接从微信红包扣款");
        return new PayState(200,"支付成功",amount);
    }
}

PayState

/**
 * 支付状态
 * @author lijun
 * @since 2018-03-16 13:56
 */
public class PayState {
    private int code;
    private Object data;
    private String msg;

    public PayState(int code, String msg, Object data) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    @Override
    public String toString() {
        return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
    }
}

OrderNoStrategy

/**
 * OrderNoStrategy
 *
 * @author lijun
 * @since 2018-03-16 14:24
 */
public class OrderNoStrategy {

    /**
     * 阿里支付
     */
    private static final String ALI_PAY = "1";

    private static final String WX_PAY = "1";

    /**
     * 支付
     *
     * @param userId    用户ID
     * @param amount    支付金额
     * @param orderType 支付类型
     * @return
     */
    PayState pay(String userId, double amount, String orderType) {
        Payment payment = null;
        if (ALI_PAY.equals(orderType)) {
            payment = new AliPay();
        } else if (WX_PAY.equals(orderType)) {
            payment = new WechatPay();
        } else {
            payment = new AliPay();
        }
        return payment.pay(userId, amount);
    }
}

调用:

  @Test
    public void payNoStrategy() throws Exception {
        OrderNoStrategy order = new OrderNoStrategy();
        PayState payState = order.pay("lijun", 200,"1");
        System.out.println(payState);
    }

输出:

欢迎使用支付宝
查询账户余额,开始扣款
支付状态:[200],支付成功,交易详情:200.0

功能是实现了,但是有什么缺点呢!上面只是实现了支付宝支付和微信支付,如果再添加银联卡支付OrderNoStrategy.pay() 得再加一个else if 如果支付渠道变的很多就会出现非常的多的if else if 。怎么消除这些if else 使用策略模式。 Payment 相当于(策略接口) AliPay(策略的实现) WechatPay(策略的实现) Order(上下文) 。

Order

/**
 * 订单
 *
 * @author lijun
 * @since 2018-03-16 14:03
 */
public class Order {

    /**
     * payment 支付接口
     */
    private Payment payment;

    public Order(Payment payment) {
        this.payment = payment;
    }

    /**
     * 上下文支付 和具体的策略类交互
     *
     * @param userId
     * @param amount
     * @return
     */
    PayState pay(String userId, double amount) {
        return payment.pay(userId, amount);
    }
}

测试:

   @Test
    public void pay() throws Exception {
        Order order = new Order(new AliPay());
        PayState payState = order.pay("lijun", 200);
        System.out.println(payState);
    }

输出:

欢迎使用支付宝
查询账户余额,开始扣款
支付状态:[200],支付成功,交易详情:200.0

这样利用策略模式实现了支付,如果要再添加一种支付,变的非常简单只需要实现Payment 其他代码都不需要修改!客户端测试只需要传入新添加的支付的实现类即可。这样就消除了多个 if else。

源码地址

posted on 2018-03-16 15:33  未亦末  阅读(245)  评论(0编辑  收藏  举报