策略者模式的特点

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

比如先设计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. Model-View-Controller Explained in C++

    The Permanent URL is: Model-View-Controller Explained in C++. The Model-View-Controller (MVC) is not ...

  2. 10秒完成Linux系统pip在线安装

    对于Python开发攻城狮及系统运维攻城狮来说,pip的安装那是必不可少的一个过程.鉴于网上很多安装过程写得过于复杂,本人根据pip官方手册总结了以下最为快捷的安装方式,只需要2步操作. curl h ...

  3. Ionic Framework 4 介绍

    Ionic Framework 4是一个开源UI工具包,用于使用Web技术(HTML,CSS和JavaScript)构建高性能的高质量移动和桌面应用程序.Ionic Framework专注于前端用户体 ...

  4. Kafka基本概念介绍

    Kafka官方介绍:Kafka是一个分布式的流处理平台(0.10.x版本),在kafka0.8.x版本的时候,kafka主要是作为一个分布式的.可分区的.具有副本数的日志服务系统(Kafka™ is ...

  5. SYN5006型电机同步编码脉冲分配器

    SYN5006型电机同步编码脉冲分配器 编码器信号分配板增量式编码器脉冲分配器使用说明视频链接: http://www.syn029.com/h-pd-81-0_310_13_-1.html 请将此链 ...

  6. Python连载11-Python中os.path模块简介

    一.os.path(和路径相关的木块) 1.函数:abspath() (1)含义:将路径转化为绝对路径的形式(absolute path) (2)格式:os.path.abspath(相对路径) (3 ...

  7. Python调试器-pdb的使用

    [简介] pdb是python自带的一个包,为python程序提供了一种交互的源代码调试功能. [使用方法] 1. 使用命令: python -m pdb xxx.py #可以直接进入单步执行模式 2 ...

  8. memcache常见现象(一)雪崩现象

    memcache常见现象(一)雪崩现象 解释:memcached雪崩现象就是因为缓存服务器出现问题导致数据库压力增大,导致数据库不能正常运行. 1.很多大的公司网站可能会有很多台缓存服务器,这样如果其 ...

  9. ubuntu16.04基本设置

    1. ubuntu16.04开启ssh https://jingyan.baidu.com/article/f54ae2fc6f9eef1e93b8497a.html 2. windows 远程桌面连 ...

  10. .netcore Control调用View方法

    控制器代码如下: 视图代码如下: 完整项目代码参考网址:https://github.com/gamecc666/BackTipFrontProject 版权声明:本文为博主原创文章,如需转载,请标明 ...