设计模式----策略模式

前言

一个具体的业务场景。

在很多电商网站或者有支付场景的系统中,支持多种支付方式,比如使用银行卡,微信或者支付宝等,那么实际在支付系统内部,不同的支付方式需要请求不同的第三方接口,比如银行卡支付方式需要请求网联,微信支付需要调用微信的API,支付宝则使用支付宝的API。
在这里插入图片描述

未使用设计模式

对于上面的场景,如果在没有使用设计模式时,我们的代码一般都是用下面的方式处理。

public class PaymentService {

    CreditService creditService;

    WeChatService weChatService;

    AlipayService alipayService;

    public void payment(PaymentType paymentType, BigDecimal amount) {
        if (PaymentType.Credit == paymentType) {
            creditService.payment();
        } else if (PaymentType.WECHAT == paymentType) {
            weChatService.payment();
        } else if (PaymentType.ALIPAY == paymentType) {
            alipayService.payment();
        } else {
            throw new NotSupportPaymentException("paymentType not support");
        }
    }
}

enum PaymentType {
    Credit, WECHAT, ALIPAY;
}

这种使用if…else的方式虽然能支持现有的业务需求,但是当业务需求发生改变时,比如增加新的支付方式,或者将某一个支付方式下线,则需要对PaymentService进行修改,显然这种设计不符合开闭原则(对扩展开放,对修改关闭),修改之后需要重新对其他的支付方式进行测试。

弊端:
不符合开闭原则
不能做到自由切换
if…else逻辑复杂,代码结构混乱
扩展性差
。。。

总之,这种方式就是很low,那么接下来我们使用策略模式来进行改造。

策略模式的定义

策略设计模式是一种行为设计模式。当在处理一个业务时,有多种处理方式,并且需要再运行时决定使哪一种具体实现时,就会使用策略模式。

这个定义和我们的例子说的一回事儿,在支付业务中,有三种付款方式,程序运行时使用哪种方式由用户选择,根据用户选择执行不同的逻辑。

策略模式结构

首先,我们需要将支付方式这一行为抽象为一个策略接口,代表支付方式的抽象。

public interface PaymentStrategy {

    public void payment(BigDecimal amount);
    
}

然后我们再针对需要支持的三种支付方式建立对应的策略实现类。

银行卡支付策略

public class CreditPaymentStrategy implements PaymentStrategy{
    @Override
    public void payment(BigDecimal amount) {
        System.out.println("使用银行卡支付" + amount);
        // 去调用网联接口
    }
}

微信支付策略

public class WechatPaymentStrategy implements PaymentStrategy{
    @Override
    public void payment(BigDecimal amount) {
        System.out.println("使用微信支付" + amount);
        // 调用微信支付API
    }
}

支付宝支付策略

public class AlipayPaymentStrategy implements PaymentStrategy {
    @Override
    public void payment(BigDecimal amount) {
        System.out.println("使用支付宝支付" + amount);
        // 调用支付宝支付API
    }
}

然后重新实现我们的支付服务PaymentService。

public class PaymentService {
    
    /**
    * 将strategy作为参数传递给支付服务
    */
    public void payment(PaymentStrategy strategy, BigDecimal amount) {
        strategy.payment(amount);
    }
}

发现了吗?我们将支付策略作为参数传递给支付服务,在支付服务中只需要按照运行时传的支付策略对象进行支付就可以了。

我们来测试一下使用策略模式之后的代码。

public class StrategyTest {

    public static void main(String[] args) {

        PaymentService paymentService = new PaymentService();

        // 使用微信支付
        paymentService.payment(new WechatPaymentStrategy(), new BigDecimal("100"));

        //使用支付宝支付
        paymentService.payment(new AlipayPaymentStrategy(), new BigDecimal("100"));

    }
}

运行结果:
在这里插入图片描述

在使用了策略模式之后,在我们的支付服务PaymentService中便不需要写复杂的if…else,如果需要新增加一种支付方式,只需要新增一个新的支付策略实现,这样就满足了开闭原则,并且对其他支付方式的业务逻辑也不会造成影响,扩展性很好。

策略模式类图

按照惯例,我们来看一下策略模式的类图。
在这里插入图片描述

JDK中使用策略模式的例子

在JDK中最经典的使用策略模式的例子就是Collections.sort(List list, Comparator<? super
T>
c)方法,这个方法接受一个比较器Compartor参数,客户端在运行时可以传入一个比较器的实现,sort()方法中根据不同实现,按照不同的方式进行排序。

策略模式使用场景

在实际工作中,会有很多场景可以使用策略模式,比如上面例子中的多个支付方式,再比如与不同的第三方销售渠道对接等等。

总结一下

1.如果在一个系统里面有许多类,它们仅仅在行为上有区别,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
2.一个系统需要动态地在几种算法中选择一种;
3.如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值