策略者模式的特点

在设计类的继承体系时,我们会刻意的把公共的部分都提取到基类中

比如先设计Person类,把人类都具有的行为放到这个Person,特有的行为设计成抽象方法,让子类具体去实现, 这样后续无论我们再去构造学生,还是构造老师,大家都继承Person,就达到了代码复用的目的

但是这样问题就来了,对老师类来说,需要有教学的行为,假如这个方法以抽象方法的形式放在基类,那么对于继承了Person的学生类来说就不对了,因为没有要求学生一定会教学,但是现在学生就得实现这个方法

如果我们把老师的教学的行为作为 老师类的私有, 这时候,小明教小李学习, 就意味着对小明来说,他需要教学的行为, 前前后后看起来就开始矛盾了, 到底怎么处理呢?

策略者模式,就解决了这个问题, 它把行为抽象成了接口,以接口+实现的方式,解决上面的问题, 就上面的例子来说,可以把教学设计成接口,任何类,只要实现了这个接口,就可以教学,而不一定强制要求只有老师才可以实现它

总的来说,策略模式,就是将行为抽象成接口+实现的模式

Netty中策略者模式的使用

netty的bossgroup中接收到了新的连接之后会使用选择器Chooser,从WorkerGroup中选择出一个EventLoop, 然后把这个连接注册进选出的 EventLoop

netty的选择器,使用的就是策略者模式,将选择的行为 设计成接口,不同的选择器根据自己不同的需求用不用的方式实现选择器接口

行为接口

@UnstableApi
public interface EventExecutorChooserFactory { EventExecutorChooser newChooser(EventExecutor[] executors);
@UnstableApi
interface EventExecutorChooser {
EventExecutor next();
}
}

选择器不同的实现:

if (isPowerOfTwo(executors.length)) {// todo 如果是2的指数倍, 返回PowerOfTwoEventExecutorChooser
return new PowerOfTwoEventExecutorChooser(executors);
} else {// todo 否则返回同样的实例
return new GenericEventExecutorChooser(executors);
}

根据线程执行器的数量确定使用那种具体的行为

行为1:PowerOfTwoEventExecutorChooser

private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
} @Override
public EventExecutor next() {
return executors[idx.getAndIncrement() & executors.length - 1];
}

主要看它的executors[idx.getAndIncrement() & executors.length - 1]

进行速度更快的与运算

1 & 1 = 1
1 & 0 = 0
0 & 1 = 0

当数组的长度是2的幂次方时, 用二进制表示就是1111... 全是1, 再减去1 ,就是0111...

无论前面的数是谁,对一个 0111... 进行与运算,得到的结果就是从0-0111...大小的数, 循环往复

行为2:GenericEventExecutorChooser

private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors; GenericEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
} @Override
public EventExecutor next() {
// todo 从0开始到最后一个, 再从零开始,到最后一个
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}

主要的一步就是Math.abs(idx.getAndIncrement() % executors.length)

可以看到,从0开始一直往后对数组的长度取余数,小数对大数取余数=小数, 保证了数组的下标从0开始递增, 自己对自己取余数=0,保证了最大值是 数组的长度减一, 如此往复

Netty中的策略者模式的更多相关文章

  1. Netty中的装饰者模式

    装饰者的应用 所谓装饰者,说白了,目的就是对现有的对象进行增强,装饰者设计模式最大的优点就是,它在扩展类原有功能的基础上还避免的类爆炸的情况 Netty中的装饰者模式的应用 ByteBuf是netty ...

  2. Netty中的责任链模式

    适用场景: 对于一个请求来说,如果有个对象都有机会处理它,而且不明确到底是哪个对象会处理请求时,我们可以考虑使用责任链模式实现它,让请求从链的头部往后移动,直到链上的一个节点成功处理了它为止 优点: ...

  3. 策略(strategy)模式

    Head First一书中对于策略(strategy)模式的正式定义是:策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户. 为了介绍这个算法,书中讲了 ...

  4. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  5. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  6. Springboot中实现策略模式+工厂模式

    策略模式和工厂模式相信大家都比较熟悉,但是大家有没有在springboot中实现策略和工厂模式? 具体策略模式和工厂模式的UML我就不给出来了,使用这个这两个模式主要是防止程序中出现大量的IF ELS ...

  7. 在商城系统中使用设计模式----策略模式之在spring中使用策略模式

    1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...

  8. Reactor 模式在Netty中的应用

    Reactor 模式在Netty中的应用 典型的Rector模式 mainReactor 服务端创建成功后,会监听Accept操作,其中ServerSocketchannel中的PipeLine中现在 ...

  9. netty中的ByteBuf

    网络数据的基本单位总是字节.Java NIO 提供了 ByteBuffer 作为它 的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐. Netty 的 ByteBuffer 替代品是 ByteB ...

随机推荐

  1. C++界面库(十几种,很全)

    刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG  Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自 ...

  2. [java代码库]-简易计算器(第一种)

    简易计算器(效果如图所示) 第一种方案:采用Javascript+html完成计算器,支持+-*/,结果显示不允许使用input输入域(可以考虑使用<span>) <html> ...

  3. Qt学习虚拟机--基于MSYS2-MinGW环境并带有各种开源的软件库!

    Qt学习虚拟机--基于MSYS2-MinGW环境并带有各种开源的软件库!虚拟机地址,VM10和以上:http://pan.baidu.com/s/1slcTA49包含两个分卷压缩包,加起来5GB多. ...

  4. 老雷socket编程之认识常用协议

    老雷socket编程之常见网络协议 1.ip IP协议是将多个包交换网络连接起来,它在源地址和目的地址之间传送一种称之为数据包的东西, 它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求. ...

  5. 算法与数据结构基础 - 队列(Queue)

    队列基础 队列具有“先进先出”的特点,用这个特点我们可以用它来处理时间序列相关或先后次序相关的问题,例如 LeetCode题目 933. Number of Recent Calls,时间复杂度O(1 ...

  6. Python 爬虫从入门到进阶之路(十一)

    之前的文章我们介绍了一下 Xpath 模块,接下来我们就利用 Xpath 模块爬取<糗事百科>的糗事. 之前我们已经利用 re 模块爬取过一次糗百,我们只需要在其基础上做一些修改就可以了, ...

  7. 网络学习笔记(三):HTTP缓存

      HTTP缓存是一种保存资源副本并在下次请求时直接使用该副本的技术,合理的使用缓存可以有效的提升web性能.   浏览器将js文件.css文件.图片等资源缓存,当下次请求这些资源时,可以不发送网络请 ...

  8. Python绘制语谱图+时域波形

    """Python绘制语谱图""" """Python绘制时域波形""" # 导 ...

  9. Python基础-组织列表

    1.字符串的几个常用方法 name = ''adb lovelace '' name.title() 首字母大写 name.upper() 全部大写 name.lower() 全部小写 2.组织列表操 ...

  10. MVC模式的介绍(C#)

    MVC模式的介绍(C#)   Benefits在开发项目中使用“模型-视图-控制器(MVC)”模式的好处在于可以完全消除商业流程和应用表达层之间的相互影响.此外,还可以获得一个完全独立的对象来控制表达 ...