策略模式

策略模式定义一系列算法并封装起来,使它们可互换。在电商项目支付流程中,用户选择支付方式的情景适合使用策略模式。通过订单类、支付渠道接口和不同支付渠道的实现,如支付宝、微信和银联,实现用户端选择支付方式的功能。使用枚举类表示支付类型,方便扩展。此外,策略模式也在爬虫项目和Spring框架中有所应用。
摘要由CSDN通过智能技术生成

策略模式(Strategy)

概述

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

应用场景

  根据用户的需求处理数据时,需要对算法做出选择。这里的算法是指固定的算法(不再发生变化)。采用策略模式的好处是相比传统的switch或者if else更方便扩展,而且算法与用户端代码解耦。
  之前研究设计模式的时候举的都是生活中的例子,后来觉得应该多举一些实际开发中用到的场景,这样才更便于理解,同时也可以在开发中选择适当场景使用。
  把之前做的电商项目的支付流程提炼了一下,其中用户选择支付方式的情景就很适合使用策略模式。
  各位客官,请往下看。

代码演示

首先看下电商常用的下单流程。
在这里插入图片描述
订单类

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

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

	//支付方法
    //完美地解决了switch的过程,不需要在代码逻辑中写switch了
    //更不需要写if    else if
    public PayState pay(Payment payment){
        return payment.pay(this.uid,this.amount);
    }

}

支付渠道接口

public interface Payment {
	//uid 用户名		amount 交易金额
    public PayState pay(String uid, double amount);

}

支付状态类

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

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

支付宝交易渠道

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

微信交易渠道

public class WechatPay implements Payment {
    @Override
    public PayState pay(String uid, double amount) {
        System.out.println("欢迎使用微信支付");
        System.out.println("直接从微信红包扣款");
        return new PayState(200,"支付成功",amount);
    }
}

银联交易渠道

public class UnionPay implements Payment {
    @Override
    public PayState pay(String uid, double amount) {
        System.out.println("欢迎使用银联卡支付");
        System.out.println("查询账户余额,开始扣款");
        return new PayState(200,"支付成功",amount);
    }
}

测试类

public class PayStrategyTest {

    public static void main(String[] args) {

        //省略把商品添加到购物车,再从购物车下单
        //直接从定单开始
        Order order = new Order("1","20180311001000009",324.45);

        //开始支付,选择微信支付、支付宝、银联卡、京东白条、财付通...
        //每个渠道它支付的具体算法是不一样的
        //基本算法固定的

        //这个值是在支付的时候才决定用哪个值
        System.out.println(order.pay(new AliPay()));
    }
}

  以上代码就可以实现由用户选择支付方式的功能,用户选择了支付宝,输出结果为:在这里插入图片描述
  但是这里又遇到了之前在工厂方法中遇到的问题,需要测试代码(用户端代码)自己来new对象new AliPay(),这个过程中就容易出现错误,还是让用户端来选择比较方便;还有就是假如我们需要修改支付类名称,用户端同样需要修改

修改订单类:

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

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

    public PayState pay(PayType payType){
        return payType.get().pay(this.uid,this.amount);
    }
}

新增支付类型枚举类

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 get(){ return this.payment;}
}

修改测试类

public class PayStrategyTest {
    public static void main(String[] args) {
        Order order = new Order("1","20180311001000009",324.45);
        System.out.println(order.pay(PayType.ALI_PAY));
    }
}

  这里再多说一句,为什么我们使用枚举类,而不是用常量来表示若干种支付方式呢?
  因为在开发中发现当一组常量之间存在一定的关系时(这里的支付方式因为都很类似),使用枚举会使得程序易于扩展;且清晰。

  当然,我们在实际开发中还有很多时候都使用到了策略模式:
  之前做的爬虫项目,需要爬去百度,新浪,搜狗中的内容。然而每个网站的爬取规则是不同的,就可以将爬取规则写成策略模式。
  在Spring中BeanFactory有很多子类,ListableBeanFactory等,而具体使用哪种工厂是由用户决定的,这里也是用到了策略模式。

一图流

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值