策略模式总结

策略模式

策略模式,实质就是封装了一些算法,让算法可以互相替换,用户可以自由选择这些算法进行操作。大话设计模式一书中,针对策略模式的引出写的还是比较不错的,可以借鉴。策略模式本身理解起来没什么难点,但是在实际应用中其本身主要结合工厂模式一起使用。Java中常用的集合比较器,就是策略模式的一种应用,除此之外,Spring中很多BeanFactory的实现,在配置BeanFactory的时候,选择何种factory,这其实就是一种策略的选择,也算是策略模式的一种。针对策略模式其他的总结,已经有前辈做的非常不错了,如这篇博客:最好的策略模式讲解文章,下图是策略模式的结构图,依旧来自大话设计模式一书。


先直接上实例吧


Payment接口

public interface Payment {

    //写在这里用户就不用去new相应的支付对象
    //种类每增加一个支付渠道,这里就要被维护一次。
//    public final static Payment ALI_PAY = new Alipay();
//    public final static Payment UnionPay = new UnionPay();
//    public final static Payment WeChatPay = new WeChatPay();


    public PayState pay(String uid,double amount);

}

Alipay类,这里只贴出这个类,其余三个不再贴出

public class Alipay implements Payment{
    public PayState pay(String uid, double amount) {
        System.out.println("欢迎使用支付宝进行支付");
        System.out.println("查询账户余额,开始扣款");
        return new PayState(200,"成功支付",String.valueOf(amount));
    }
}

PayState类,其实就是一个返回结果,作用和一个字符串差不多

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;
    }

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

Order订单类,其中有结算方法

public class Order {

    private String uid;

    private String orderId;

    private double amount;

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

//    订单的结算方法
//    public PayState pay(Payment payment){
//        return payment.pay(this.uid,this.amount);
//    }


    //这个参数完全可以用接口代替,但是这里用到的是枚举,为什么没有用接口
    //能完美的解决switch的过程,这里就不用根据用户选择的类型来进行判断了
    //不用写一长串的判断语句,不需要写if-else进行支付渠道的判断
    public PayState pay(PayType payType){
        return payType.getPayment().pay(this.uid,this.amount);
    }
}

注释代码中,是没有使用枚举的时候,如果这个时候新增加一种支付方式:MeiTuanPay,Payment这个接口就需要重新维护一次,在其中增加一个常量 public final static Payment MEITUAN_PAY = new MeiTuanPay();这样在实际生产过程中无疑是不好的,所以这里就采用了枚举,既避免了工厂模式的繁琐,也能巧妙的实现指定的功能。

PayType的枚举,其中的getPayment能根据选中的枚举类型,创建指定的支付类型

public enum PayType {
    ALI_PAY(new Alipay()),WECHAT_PAY(new WeChatPay()),UNION_PAY(new UnionPay()),JD_PAY(new JDPay());

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

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

使用了PayType枚举之后,如果新增了Meituan_Pay,只需要在其中增加MEITUAN_PAY(new MeituanPay())即可

测试类:

public class PayStrategyTest {

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

        //开始支付,微信支付,支付宝,银联卡,京东白条
        //每个渠道支付的具体算法是不一样的,但是基本算法是固定的
        //System.out.println(order.pay(new Alipay()));
        System.out.println(order.pay(PayType.ALI_PAY));
        System.out.println(order.pay(PayType.UNION_PAY));
        System.out.println(order.pay(PayType.WECHAT_PAY));

        System.out.println(order.pay(PayType.JD_PAY));
    }

}

测试结果如下:


总结

策略模式本身比较好理解,但通常其并不单独使用,而是结合工厂模式进行使用,本文中的实例利用枚举,其实也是工厂的一种简单表示

猜你喜欢

转载自blog.csdn.net/liman65727/article/details/79703240