设计模式-策略模式(Strategy Pattern)

891 阅读4分钟

Github 源码地址

23种设计模式总览

创建型模式

结构型模式

行为型模式

定义

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

优缺点

优点:  1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点:  1、策略类会增多。 2、所有策略类都需要对外暴露。

使用场景:

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

实现

策略模式包含三个角色:

抽象策略(Strategy) :通常由接口或抽象类实现。定义了多个具体策略的公共接口,具体策略类中各种不同的算法以不同的方式实现这个接口;Context使用这些接口调用不同实现的算法。
具体策略(ConcreteStrategy) :实现Strategy接口或继承于抽象类Strategy,封装了具体的算法和行为。
环境类(Contex) :持有一个公共策略接口的引用,直接给客户端调用。

我们在电商平台购物,到支付支付的时候,通常会有很多的支付方式可以选择,比如说有:支付宝、微信、银联云闪付等等。

这里我们就可以思考一下,电商平台在执行支付这个操作的时候,是如何根据我们选择的支付方式来判断和执行之后的操作的呢?

最容易想到的,可能就是在代码中根据用户选择的支付方式进行一系列的 if else 操作了把。

if (Objects.equals(paymentWay, "支付宝")) {
    支付宝支付处理逻辑...
} else if (Objects.equals(paymentWay, "微信")) {
    微信支付处理逻辑...
} else if (Objects.equals(paymentWay, "银联云闪付")) {
    银联云闪付支付处理逻辑...
} else if (Objects.equals(paymentWay, "xxx")) {
    xxx支付处理逻辑...
}

看看上面的代码是不是觉得头晕胸闷。每个 if else 中都有大量的逻辑处理,新增一个支付方式,就需要新增一个 if else ,这样写了之后,不仅代码的可读性低,而且后期的维护成本也是大大的增高了。而且每次的修改出错的几率也是比较高。

所以这里就适合使用策略模式来进行一波重构。

策略模式重构

我们可以把支付这个操作抽象为一个策略接口。

//支付方式
public interface Payment {
    void payment();
}

然后定义不同的支付方式的具体实现。

支付宝支付:

public class AliPayPayment implements Payment {

    @Override
    public void payment() {
        System.out.println("支付宝支付");
    }
}

微信支付:

public class WechatPayPayment implements Payment {

    @Override
    public void payment() {
        System.out.println("微信支付");
    }
}

银联云闪付:

public class UnionPayPayment implements Payment {

    @Override
    public void payment() {
        System.out.println("银联云闪付");
    }
}

再定义策略模式的容器类。

public class PaymentContext {

    private Payment payment;

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

    public void payment(){
        payment.payment();
    }
}

定义好了之后,现在再看支付的时候,我们只需要根据不同的支付方式,初始化策略容器并传入对应支付方式实现,然后调用策略容器的 payment() 方法即可。

class Test {
    public static void main(String[] args) {
        //支付宝支付
        PaymentContext aliPay = new PaymentContext(new AliPayPayment());
        aliPay.payment();
        //微信支付
        PaymentContext wechatPay = new PaymentContext(new WechatPayPayment());
        wechatPay.payment();
        //银联云闪付
        PaymentContext unionPay = new PaymentContext(new UnionPayPayment());
        unionPay.payment();
    }
}
支付宝支付
微信支付
银联云闪付