策略模式概述
- 对象的某个行为,在不同场景有不同的实现方式(如不同的支付方式),这样就可以将这些实现方法定义成一组策略模式,每个实现类对应一个策略,在不同场景就使用不同实现类,并可以自由切换策略。
- 策略模式需要一个策略接口,不同策略实现不同的实现类,再具体业务中仅持有该策略接口,根据不同场景使用不同实现类即可
策略模式结构
-
结构示意图
-
角色
- Strategy(抽象策略类):策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法
- Context(业务上下文类):上下文包含strategy抽象类接口声明的变量, 持有一个策略类的引用,最终给客户端调用
- ConcreteStrategy (具体策略): 实现策略接口的类 ,提供具体实现方法
策略模式的优缺点和适用环境
-
优点:
- 干掉繁琐的if-else/switch逻辑判断地狱;
- 代码优雅、可复用、可读性好
- 符合开闭原则,扩展性好,便于后期业务拓展和维护
-
缺点:
- 如果策略很多,会造成策略类膨胀
- 使用者必须清楚所有策略类及其应用场景
-
适用环境:
- 对某个具体业务有不同的实现方式,将来也会有业务扩展
- 代码中使用过长if/else if或switch逻辑判断
示例代码
支付场景中,选择不同的支付方式
- 策略接口
/**
* 支付策略接口
*/
public interface IPayStrategy {
void pay(Order order);
}
- 策略实现类
/**
* 微信支付
*/
public class WeChatPay implements IPayStrategy{
@Override
public void pay(Order order) {
System.out.println("微信收款"+order.getAmount()+"元");
}
}
/**
* 支付宝支付
*/
public class ALiPay implements IPayStrategy{
@Override
public void pay(Order order) {
System.out.println("支付宝到账"+order.getAmount()+"元");
}
}
- 策略上下文
/**
* 支付上下文
*/
public class PayContext {
private IPayStrategy payStrategy;
Map<String,IPayStrategy> map= new HashMap<>();
private PayContext(){
map.put("支付宝支付",new ALiPay());
map.put("微信支付",new WeChatPay());
}
/**
* 饿汉式 单例模式
*/
private static PayContext payContext=new PayContext();
public static PayContext getInstance(){
return payContext;
}
//获取策略实例
public IPayStrategy getPayStrategy(Order order) {
return map.get(order.getPaymentType());
}
}
- 实体类
/**
* 订单类
*/
@Data @AllArgsConstructor @NoArgsConstructor
public class Order {
/**
* 金额
*/
private int amount;
/**
* 支付类型
*/
private String paymentType;
}
- 测试类
public static void main(String[] args) {
PayContext context = PayContext.getInstance();
Order orderWeChat=new Order(1,"微信支付");
Order orderALi=new Order(2,"支付宝支付");
IPayStrategy weichatPayStrategy = context.getPayStrategy(orderWeChat);
IPayStrategy aLiPayStrategy = context.getPayStrategy(orderALi);
weichatPayStrategy.pay(orderWeChat);
aLiPayStrategy.pay(orderALi);
}
测试结果
微信收款1元
支付宝到账2元