网络异常,图片无法展示
|
前言
在业务开发中,我们最经常使用到的判断就是if...else,只要涉及到多种策略的实现方式,我们脑海中就会使用这个判断。有时候产品需求的不明确,一个版本迭代来一种判断,随着时间的推移,这个实现方法就会变得又长又臭,那有什么办法可以来觉得呢,通过学习策略模式,他能够很好的帮我们解决这个问题。
纲要
在学习之前,有一句话我觉得比设计模式更重要。
设计原则和思想比设计模式更加普适和重要
网络异常,图片无法展示
|
什么是策略模式?
简单的来说,就是定义一系列算法,封装每个算法,并使它们可以互换。
策略让算法独立于使用它的客户端而变化。
1. 三个关键角色
网络异常,图片无法展示
|
三个关键角色
2. 目的
实现不同的策略,将策略分离
3. 为什么要使用策略模式
主要有三个原因
网络异常,图片无法展示
|
为什么使用策略模式?
优缺点
网络异常,图片无法展示
|
优缺点
场景分析
通过第一部分,我们对策略模式有了一个大概的认识,那他主要针对于什么场景呢
- 需要动态切换不同算法
- 多重的条件选择业务场景
- 客户端只关心调用,不关心算法细节
- 分离策略
源码案例
网络异常,图片无法展示
|
源码案例
我们可以通过优秀的代码中学习策略模式的实现
SimpleInstantiationStrategy中分析出它的关键角色
可以从命名中看出,SimpleInstantiationStrategy是其中的某一个策略,我们在写策略模式的时候最好也以Strategy为结尾,表名这就是个策略。
1.抽象策略类
public interface InstantiationStrategy { Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3) throws BeansException; Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3, Constructor<?> var4, Object... var5) throws BeansException; Object instantiate(RootBeanDefinition var1, @Nullable String var2, BeanFactory var3, @Nullable Object var4, Method var5, Object... var6) throws BeansException; }
2.具体策略类
public class SimpleInstantiationStrategy implements InstantiationStrategy { private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal(); public SimpleInstantiationStrategy() { } @Nullable public static Method getCurrentlyInvokedFactoryMethod() { return (Method)currentlyInvokedFactoryMethod.get(); } public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { //... } public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, Constructor<?> ctor, Object... args) { //... } public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Object factoryBean, Method factoryMethod, Object... args) { //... }
3.上下文信息类
这里没有找到上下文信息类,我们可以理解为上下文就是来存取策略的一个地方。在这里可以与工厂模式有一个很好的结合,在实践demo中给大家展示。
实践
与工厂模式结合:
上下文信息类:
@Component public class rulesFactory { private static final Map<Integer,RuleStrategy> map = new HashMap<>(20); @Resource public selectStrategy selectStrategy; //@PostConstruct 用来修饰一个非静态的void()方法.而且这个方法不能有抛出异常声明。在服务器加载Servlet的时候运行,并且只会被服务器调用一次 @PostConstruct public void init(){ map.put(1,selectStrategy); } public RuleStrategy creator(Integer type) { return map.get(type); } }
抽象策略(Strategy)角色:
public interface RuleStrategy<T extends RulesProcessorBO> { void process(T t); }
环境角色(组件,直接调用工厂):
@Component public class RuleContext { @Resource private rulesFactory bizRuleFactory; public void process(RulesProcessorBO rulesProcessorBO) { bizRuleFactory.creator(rulesProcessorBO.getRuleCode()).process(rulesProcessorBO); } }
具体策略(ConcreteStrategy)角色:
@Component @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public class selectStrategy implements RuleStrategy<selectProcessorBo> { @Autowired private ManagerMapper managerMapper; @Override public void process(selectProcessorBo rulesProcessorBO) { Manager m = managerMapper.getById("1"); System.out.println(m.toString()); } }
这就是一个策略模式的实现,可以看出代码量一下就上去了,如果在规则简单而且情况少的情况下,我们可能就不需要再去使用策略模式,因为它不够直观。