0x01:策略模式简介
策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要交个人所得税,但是根据个人的收入情况,个人所得税的计算算法是有不同的策略的。
我想大家都看过《三国演义》,其中刘备娶孙夫人时,诸葛亮交给赵云三个
锦囊,就是三个策略
锦囊一:到达东吴,先去拜会乔国老
锦囊二:刘备贪念美色不思离开,就对他谎称曹操大军压境
锦囊三:如果被东吴军队追赶,求孙夫人解围
策略模式的UML类图如下:
主要角色分析:
抽象策略角色(Strategy):策略类,通常由一个接口或者抽象类实现;
具体策略角色(ConcreteStrategyA):包装了相关的算法和行为;
上下文角色(Context):持有一个策略类的引用,最终给客户端调用;
Context是上下文,用一个ConcreteStrategy来配置,维护一个Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。
0x02:策略模式实现
Context:Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
Strategy:抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。algorithm是运算法则的意思。
ConcreteStrategy:具体策略角色,用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。
策略模式测试代码:可以依次更换策略,测试一下策略模式。
0x03:策略模式在JDK的运用
在多线程编程中,经常使用线程池来管理线程,以减缓线程频繁的创建和销毁带来的资源的浪费,其中ThreadPoolExecutor类中的RejectedExecutionHandler参数就是一个使用了策略模式的典型例子。
ThreadPoolExecutor的构造函数
RejectedExecutionHandler接口
RejectedExecutionHandler的四种策略实现
CallerRunsPolicy:该策略并没有抛弃任何的任务,由于线程池中已经没有了多余的线程来分配该任务,该策略是在当前线程(调用者线程)中直接执行该任务;
AbortPolicy:该策略是直接将提交的任务抛弃掉,并抛出RejectedExecutionException异常;
DiscardPolicy:该策略也是将任务抛弃掉(对于提交的任务不管不问,什么也不做),不过并不抛出异常。
DiscardOldestPolicy:该策略是当执行器未关闭时,从任务队列workQueue中取出第一个任务,并抛弃这第一个任务,进而有空间存储刚刚提交的任务。使用该策略需要特别小心,因为它会直接抛弃之前的任务。
领取专属 10元无门槛券
私享最新 技术干货