0x01:策略模式简介

策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要交个人所得税,但是根据个人的收入情况,个人所得税的计算算法是有不同的策略的。

我想大家都看过《三国演义》,其中刘备娶孙夫人时,诸葛亮交给赵云三个

锦囊,就是三个策略
  • 锦囊一:到达东吴,先去拜会乔国老

  • 锦囊二:刘备贪念美色不思离开,就对他谎称曹操大军压境

  • 锦囊三:如果被东吴军队追赶,求孙夫人解围

策略模式的UML类图如下:

主要角色分析:

  • 抽象策略角色(Strategy): 策略类,通常由一个接口或者抽象类实现;

  • 具体策略角色(ConcreteStrategyA):包装了相关的算法和行为;

  • 上下文角色(Context):持有一个策略类的引用,最终给客户端调用;

Context是上下文,用一个ConcreteStrategy来配置,维护一个Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。

0x02:策略模式实现

Context:Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}//上下文接口public void contextInterface() {strategy.algorithmInterface();}}

Strategy:抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。algorithm是运算法则的意思。

public abstract class Strategy {//算法方法public abstract void algorithmInterface();}

ConcreteStrategy:具体策略角色,用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。

public class ConcreteStrategyA extends Strategy {@Overridepublic void algorithmInterface() {System.out.println("ConcreteStrategyA 实现");}}public class ConcreteStrategyB extends Strategy {@Overridepublic void algorithmInterface() {System.out.println("ConcreteStrategyB 实现");}}public class ConcreteStrategyC extends Strategy {@Overridepublic void algorithmInterface() {System.out.println("ConcreteStrategyC 实现");}}

策略模式测试代码:可以依次更换策略,测试一下策略模式。

public class Client{public static void main(String[] args) {Context context = null;context = new Context(new ConcreteStrategyA());context.contextInterface();context = new Context(new ConcreteStrategyB());context.contextInterface();context = new Context(new ConcreteStrategyC());context.contextInterface();}}

0x03:策略模式在JDK的运用

在多线程编程中,经常使用线程池来管理线程,以减缓线程频繁的创建和销毁带来的资源的浪费,其中ThreadPoolExecutor类中的RejectedExecutionHandler参数就是一个使用了策略模式的典型例子。

ThreadPoolExecutor的构造函数

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

RejectedExecutionHandler接口

public interface RejectedExecutionHandler {void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

RejectedExecutionHandler的四种策略实现

  • CallerRunsPolicy:该策略并没有抛弃任何的任务,由于线程池中已经没有了多余的线程来分配该任务,该策略是在当前线程(调用者线程)中直接执行该任务;

  • AbortPolicy:该策略是直接将提交的任务抛弃掉,并抛出RejectedExecutionException异常;

  • DiscardPolicy:该策略也是将任务抛弃掉(对于提交的任务不管不问,什么也不做),不过并不抛出异常。

  • DiscardOldestPolicy:该策略是当执行器未关闭时,从任务队列workQueue中取出第一个任务,并抛弃这第一个任务,进而有空间存储刚刚提交的任务。使用该策略需要特别小心,因为它会直接抛弃之前的任务。

    public static class CallerRunsPolicy implements RejectedExecutionHandler {public CallerRunsPolicy() { }public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {r.run();}}}public static class AbortPolicy implements RejectedExecutionHandler {public AbortPolicy() { }public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +e.toString());}}public static class DiscardPolicy implements RejectedExecutionHandler {public DiscardPolicy() { }public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {}}public static class DiscardOldestPolicy implements RejectedExecutionHandler {public DiscardOldestPolicy() { }public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {e.getQueue().poll();e.execute(r);}}}

你有张良计,我有过墙梯之策略模式相关推荐

  1. python123新版个人所得税计算_你有张良计,我有过墙梯之策略模式

    0x01:策略模式简介 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法.比如每个人都要交个人所得税,但是根据个人的收入情况,个人所得税的计算算法是有不同的策略的. 我想大家都看过 ...

  2. AI的张良计与过墙梯:3·15智能骚扰电话下的冰山脉络

    在今年的3·15上,果不其然AI被点名了.抛去属于"质量问题"的虚假智能产品以外,更引人关注还要数"智能骚扰电话".相关报道提到,一些所谓的"大数据企 ...

  3. 你有张良计,我有过墙梯——ListBox的悲与喜

    意图:通过点击ListBox,GridView表格切换数据源,显示不同的数据表格. 最初,我起了一些Javascript代码,收效甚微,加之不好调试,又恐耽搁进度.没有办法,找了个最笨的方法,也算是过 ...

  4. #今日论文推荐#Ladder Side-Tuning:预训练模型的“过墙梯”

    #今日论文推荐#Ladder Side-Tuning:预训练模型的"过墙梯" 如果说大型的预训练模型是自然语言处理的"张良计",那么对应的"过墙梯&q ...

  5. Ladder Side-Tuning:预训练模型的“过墙梯”

    ©PaperWeekly 原创 · 作者 | 苏剑林 单位 | 追一科技 研究方向 | NLP.神经网络 如果说大型的预训练模型是自然语言处理的"张良计",那么对应的"过 ...

  6. “你有张良计,我有过墙梯” 几行Python代码突破反爬虫机制!

    Time will tell. 1.什么是爬虫和反爬虫 爬虫是使用任何技术手段批量获取网站信息的一种方式,反爬虫是使用任何技术手段阻止别人批量获取自己网站信息的一种方式. 2.User-Agent介绍 ...

  7. 【设计模式七之策略模式】你有你的张良计,我有我的过墙梯

    Strategy模式 细说策略模式 策略模式究竟是什么模式 策略模式的场景 官宣的策略模式 代码展示 代码一 细说策略模式 提示: 博主:章飞 _906285288的博客 博客地址:http://bl ...

  8. 6 张图带你彻底搞懂分布式事务 XA 模式

    作者 | 朱晋君 来源 | 阿里巴巴云原生公众号 XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口.目前主流的数据库,比如 o ...

  9. 有服主传送玩家指令_我的世界:狗子传送机学废了?没关系,简单无脑的WiFi红石来了!...

    点击上方 蓝字 即可关注,每天有免费文章分享,欢迎留言小编看到会及时回复!!! 声明:本文素材均来源于网络,如有侵权联系删除 图酱在我的世界:狗子无用?错,是你不会用!试试大神开发的狗子回家机文章中介 ...

最新文章

  1. php循环输出sql数组吗,在PHP中循环SQL结果 – 没有获得整个数组
  2. iptables连接跟踪ip_conntrack
  3. Ubuntu LAMP
  4. 2007年度最具投资价值100强网站揭晓——博客园榜上有名
  5. python2编码_Python2字符编码
  6. 如何确定恶意软件是否在自己的电脑中执行过?
  7. 安装Veritas Backup Exec v20.3
  8. 简单的POST sql注入
  9. 《Excel数据处理与分析实战技巧精粹》扫描版[PDF]
  10. 安装Realtek RTL8111/RTL8168网卡驱动详解(error~eth0:no such device)
  11. TeKtronix TDS210数字示波器说明书
  12. php 豆瓣api_豆瓣的账号登录及PHP api操作
  13. 我是一只程序猿,沪漂一整年。
  14. win10电脑防火墙允许ping设置
  15. 全球及中国晶圆激光打标机行业投资竞争力及需求规模预测报告2022-2027年
  16. ffmpeg学习日记506-源码-av_image_copy()函数分析及功能
  17. codeforces 771 A
  18. MSP430-USC(二)
  19. Cobbler 登录web界面提示报错“Internal Server Error”
  20. 支付宝 Android SDK 吐槽+辟谣(一)

热门文章

  1. Java 中的屠龙之术:如何修改语法树?
  2. 微信公众号如何获取openid
  3. 华为鸿蒙手机有哪几款,华为哪款手机搭载鸿蒙?_科技数码通
  4. JDK的安装与配置(配图)
  5. php-cs-fixer实践
  6. 一个大学教授的精彩演讲~~
  7. DOS下读取4GB内存——梁肇新代码分析
  8. 苹果自带相册打马赛克_做电子相册不用第三方工具!直接用手机自带的功能
  9. 深度商店下载的安装包位置
  10. ROS2+DDS+RTPS