概念
策略模式(Strategy Pattern),也叫政策模式(Policy Pattern),在策略模式中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
策略模式一般主要包含三个角色:
- 上下文(Context):用来操作策略的上下文环境,屏蔽客户端对策略、算法的直接访问,封装可能存在的变化
- 抽象策略(Strategy):规定策略或算法的行为
- 具体策略(ConcreteStrategy):策略或算法的具体实现
实现
接下来以支付方式场景为例
1.创建抽象策略
public abstract class Payment {
abstract String getName();
}
2.创建具体策略
public class AliPay extends Payment {
@Override
String getName() {
return "欢迎使用支付宝支付";
}
}
public class WeChatPay extends Payment{
@Override
String getName() {
return "欢迎使用微信支付";
}
}
3.创建上下文
public class PayStrategy {
public static final String ALI_PAY="AliPay";
public static final String WECHAT_PAY="WeChatPay";
public static final String DEFAULT="AliPay";
public static Map<String ,Payment> map=new HashMap<String ,Payment>();
static {
map.put(ALI_PAY,new AliPay());
map.put(WECHAT_PAY,new WeChatPay());
}
public static Payment get(String name){
if (!map.containsKey(name)){
return map.get(DEFAULT);
}
return map.get(name);
}
}
4.测试
public class StrategyTest {
public static void main(String[] args) {
Payment pay=PayStrategy.get(PayStrategy.ALI_PAY);
System.out.println(pay.getName());
}
}
运行结果:
使用场景
- 针对同一类型问题,有多种处理方式,每一种都能独立解决问题
- 一个系统需要动态地在几种算法中选择一种
在Spring框架中的运用
在Spring DI过程中,在初始化的时候采用了策略模式。
有一个InstantiationStrategy 接口
public interface InstantiationStrategy {
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, @Nullable Object... args) throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, @Nullable Object... args)
throws BeansException;
}
还有两个策略实现类CglibSubclassingInstantiationStrategy和SimpleInstantiationStrategy
UML类图如下:
我们发现CglibSubclassingInstantiationStrategy策略类继承了SimpleInstantiationStrategy类,说明在实际运用中,多种策略之间还可以继承使用
总结
优点
- 扩展性好,复合开闭原则
- 避免使用多重条件判断,如if…else、switch…case
- 算法可以自由切换
缺点
- 所有的策略类都需要对外暴露
- 会产生许多的策略类