策略模式
定义:
定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。——《设计模式:可复用面向对象软件的基础》
角色
策略模式有三个角色,分别是:
抽象策略角色(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