策略模式

策略模式

定义:

定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。——《设计模式:可复用面向对象软件的基础》

角色

策略模式有三个角色,分别是:
抽象策略角色(Strategy):是所有具体策略类共同的接口
具体策略角色(ConcreteStrategy):是实现了抽象策略接口的具体实现类
上下文角色(Context):拥有Strategy的引用,提供具体策略。

使用场景

现在需要接收来自某系统的回调,消息回调会有很多类型,比如私聊文本消息、私聊图片消息、新好友申请、私聊语音消息等,每一种消息类型,对应不同的逻辑处理,我们最开始是想直接if-else或者switch,走不同的分支逻辑搞定,但是这样扩展性不好,不易维护,这时我们想到了策略模式。

优缺点

优点:

1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如if...else...语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。

缺点:

1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度。

模拟案例:

如下案例是模拟支付时选择不同的支付方式的情况,使用springboot为开发框架实现。

定义实体类
/**
 * 订单信息
 * @author: _先森
 */
@Data
public class Order {
    /**
     * 金额
     */
    private int amount;
    /**
     * 支付类型
     */
    private String paymentType;
/**
 * 返回结果
 * @author: _先森
 */
@Data
@AllArgsConstructor
public class PayResult {
    /**
     * 支付结果
     */
    private String result;
}
定义抽象策略角色
/**
 * 支付接口
 * @author: _先森
 */
public interface IPayment {
    /**
     * 支付
     * @param order
     * @return
     */
    PayResult pay(Order order);
}
定义具体策略角色
/**
 * 支付宝
 * @author: _先森
 */
@Service("Alipay")
public class Alipay implements IPayment {
    @Override
    public PayResult pay(Order order) {
        return new PayResult("支付宝支付成功");
    }
}
/**
 * 云闪付
 * @author: _先森
 */
@Service("UnionPay")
public class UnionPay implements IPayment {
    @Override
    public PayResult pay(Order order) {
        return new PayResult("云闪付支付成功");
    }
}
/**
 * 微信支付
 * @author: _先森
 */
@Service("WechatPay")
public class WechatPay implements IPayment {
    @Override
    public PayResult pay(Order order) {
        return new PayResult("微信支付成功");
    }
}
定义上下文角色
/**
 * 支付服务
 * @author: _先森
 */
@RestController
public class PayService {

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 支付接口
     * @param amount
     * @param paymentType
     * @return
     */
    @RequestMapping("/pay")
    public PayResult pay(@RequestParam("amount") int amount,
                         @RequestParam("paymentType") String paymentType) {
        Order order = new Order();
        order.setAmount(amount);
        order.setPaymentType(paymentType);

        // 根据支付类型获取对应的策略 bean

        IPayment payment = applicationContext.getBean(order.getPaymentType(), IPayment.class);

        // 开始支付
        PayResult payResult = payment.pay(order);

        return payResult;
    }
}

参考文章:
https://blog.csdn.net/Leon_Jinhai_Sun/article/details/109553671

策略模式

上一篇:DNS域名解析服务(一)——正向解析和反向解析详解


下一篇:从0到1,轻松构建数据预测模型