个人感悟之策略模式

策略模式

  策略模式到底是一个什么样子的意思呢?我们可以拿出一些例子来进行阐述:把商品添加到购物车里面去,然后我们会下单,根据金额进行支付,支付的方式也有很多比如支付宝、银行卡等,然后卖家发货,通过物流送到我们手里。这是一套我们熟悉的在淘宝上买东西的流程。策略模式就是封装算法,让算法可以相互替换,不影响使用算法的用户,用户本身知道他要采用什么算法去计算,就像用户去选择支付方式一样。我们可以使用在下面用代码实现一下

订单类

  我们首先建立一个订单类,他包含的项目包括用户ID,订单ID和订单金额,这对于我们很熟悉,因此实现也不难。

public class Order {
    private String uId;
    private String orderId;
    double amount;

    public Order(String uId, String orderId, double amount) {
        this.uId = uId;
        this.orderId = orderId;
        this.amount = amount;
    }

    public PayState pay(Payment payment) {
        return payment.pay(this.uId,this.amount);
    }
}

  接着就是支付方式类,我先定义一个接口,然后让每个支付方式去实现它。

public interface Payment {
    public PayState pay(String uId,double amount);
}

public class AliPay implements Payment {
    
    public PayState pay(String uId, double amount) {
        System.out.println("现在正在使用支付宝");
        System.out.println("您的余额充足,正在扣费");
        return new PayState(200,amount,"支付成功");
    }
}

public class WeChatPay implements Payment {
    public PayState pay(String uId, double amount) {
        System.out.println("正在使用微信支付");
        //这里我不做余额判断,先设置余额不足的情况
        System.out.println("您的余额不足,扣费失败");
        return new PayState(90,100,"请选择其他支付方式");
    }
}    

  然后就是一个支付状态的类,主要参数是余额,订单金额和支付信息。

public class PayState {
    private int code;
    private Object data;
    private String msg;

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

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

  最后我通过一个测试类来验证一下是不是符合逻辑。

public class PayStrategyTest {

    public static void main(String[] args) {
        Order order = new Order("1","cnblogjolivan",100);

        //用户选择支付方式:支付宝、银联卡、微信支付等,每个渠道具体支付的算法不一样,基本的算法是固定的,但是有选择权。
        System.out.println(order.pay(new AliPay()));
        System.out.println(order.pay(new WeChatPay()));
    }
}
-----------------------------------------------------------------------
现在正在使用支付宝
您的余额充足,正在扣费
支付状态:{code=200, 交易详情=100.0, msg='支付成功'}
正在使用微信支付
您的余额不足,扣费失败
支付状态:{code=90, 交易详情=100, msg='请选择其他支付方式'}

  但是这样我总感觉用户在选择支付方式的时候,并不能满足用户选择支付方式,因为用户根本就不知道有哪些支付方式,于是我又想到了一个思路,就是在接口里直接包装支付方式,返回一个支付类的实例。

public interface Payment {
    public final Payment Ali_Pay = new AliPay();
    public final Payment WeChat_Pay = new WeChatPay();
    public PayState pay(String uId,double amount);
}

  但是这样的方式,如果我新增一个支付方式,那么就要修改这个接口,不满足开闭原则,因此这个方法不是很好。怎么样能保证在拓展支付方式的时候,不破坏开闭原则呢?可以用到枚举方法,因为这样我们在增加支付方式的时候,就增加一个支付的入口就可以了。

public enum PayType {
    Ali_Pay(new AliPay()),
    WeChat_Pay(new AliPay());

    private Payment payment;
PayType(Payment payment){
this.payment = payment; } public Payment getPayment() { return payment; } }

  然后再回到我们的测试类,这样就可以满足我们的要求了。

public class PayStrategyTest {

    public static void main(String[] args) {
        Order order = new Order("1","cnblogjolivan",100);

        //用户选择支付方式:支付宝、银联卡、微信支付等,每个渠道具体支付的算法不一样,基本的算法是固定的,但是有选择权。
        System.out.println(order.pay(PayType.Ali_Pay));
    }
}

  这样用户就可以获取所有的支付方式,但不会知道具体支付方式的核心代码。

  其实我个人感觉策略模式和工厂模式很像,只不过工厂模式侧重对象实例的区别,而策略模式侧重执行的过程不一样。

posted @ 2018-05-22 11:35  jolivan  阅读(457)  评论(0编辑  收藏  举报