【深入理解 ByteBuf 之三 接口类拆解】1. ObjectPool 接口设计剖析

想了一下,我决定还是做更细化的拆解,也看了很多源码剖析的文章1,以及我之前也写过,一个令人难受的点就是通篇的代码解释,通篇没什么头绪,我看着没头绪,感觉写的也没什么头绪,就是在硬看硬写,看完之后仍然不知云云,不得要领,无法复刻,写完之后的感觉也是。
在步入第三部分 接口&类的解析,我决定对每个一个接口&类的定义实现都进行拆解和剖析聊一聊这样设计的好处和原因2,并拆分为小块进行整理,以小见大。
最终应该会整理出一版最终的设计脉络。

ObjectPool 接口设计

在这里插入图片描述

ObjectPool 接口实际上是对整体的池化分配做了整体的抽象和解耦

通过定义两个接口 ObjectCreator 和 Handle 接口 将创建和回收解耦可以灵活提供各类实现。

整体的控制逻辑在 Recycler 中进行实现。

package io.netty.util.internal;import io.netty.util.Recycler;/*** Light-weight object pool.* T 的类型是要池化的资源的类型* 对象池一般由 T 类持有,比如 PooledUnsafeDirectByteBuf 、 PooledDirectByteBuf* 对应 T 类持有静态的对象池,可供直接分配调用  io.netty.buffer.PooledUnsafeDirectByteBuf#newInstance(int)* @param <T> the type of the pooled object*/
public abstract class ObjectPool<T> {ObjectPool() { }/*** Get a {@link Object} from the {@link ObjectPool}. The returned {@link Object} may be created via* {@link ObjectCreator#newObject(Handle)} if no pooled {@link Object} is ready to be reused.* 获取一个 T 对象池中。* 如果对象池中没有可重用的对象,这个返回的对象可能会通过 ObjectCreator#newObject 方法获取*/public abstract T get();/*** Handle for an pooled {@link Object} that will be used to notify the {@link ObjectPool} once it can* reuse the pooled {@link Object} again.* 用于表示池化的句柄 Handle , 用于通知对象池可以再次重用已经池化的对象* @param <T>*/public interface Handle<T> {/*** Recycle the {@link Object} if possible and so make it ready to be reused.* 回收方法,如果可能得话回收 T 对象自己,并使其准备好可以再次重用* **/void recycle(T self);}/*** Creates a new Object which references the given {@link Handle} and calls {@link Handle#recycle(Object)} once* it can be re-used.* 创建一个新的对象,引用给的的 handle 并且在可以重新使用是调用 Handle 的 recycle 方法* @param <T> the type of the pooled object*/public interface ObjectCreator<T> {/*** Creates an returns a new {@link Object} that can be used and later recycled via* {@link Handle#recycle(Object)}.* 创建一个新的可用对象返回, 可以通过 recycle 方法进行回收*/T newObject(Handle<T> handle);}/*** Creates a new {@link ObjectPool} which will use the given {@link ObjectCreator} to create the {@link Object}* that should be pooled.* 创建一个新的对象池,并通过给定的 ObjectCreator 去创建应该被池化的对象*/public static <T> ObjectPool<T> newPool(final ObjectCreator<T> creator) {return new RecyclerObjectPool<T>(ObjectUtil.checkNotNull(creator, "creator"));}/*** 一个默认的对象池实现,持有一个 recycler 回收器,通过 recycler 执行对象获取*/private static final class RecyclerObjectPool<T> extends ObjectPool<T> {private final Recycler<T> recycler;RecyclerObjectPool(final ObjectCreator<T> creator) {recycler = new Recycler<T>() {@Overrideprotected T newObject(Handle<T> handle) {return creator.newObject(handle);}};}@Overridepublic T get() {return recycler.get();}}
}

这段代码涉及到对象池的设计,包括主要的接口 ObjectPool 以及与之关联的 HandleObjectCreator 接口。同时,通过内部的 RecyclerObjectPool 类实现了具体的对象池。

设计思路解析:

  1. ObjectPool 接口: 该接口定义了对象池的基本操作,主要包括从池中获取对象的 get 方法。它是一个泛型接口,这使得它可以处理各种类型的对象。

  2. Handle 接口: 这是一个用于处理池化对象的句柄接口,定义了回收对象的方法 recycle。通过这个接口,实现了对象的回收与重用。

  3. ObjectCreator 接口: 该接口定义了创建新对象的方法 newObject,它接收一个 Handle 对象,用于在创建对象时将其与对象池关联起来。这样,新创建的对象就能够被池化并通过 Handle 进行回收。

  4. RecyclerObjectPool 类: 这是 ObjectPool 接口的具体实现类,通过内部的 Recycler 类来管理对象的创建和回收。将具体的对象创建逻辑放在 Recycler 中的好处是可以实现更灵活的对象创建策略,例如通过对象池管理的对象进行初始化。

  5. Recycler 类: 这是一个抽象类,实现了对象的创建和回收逻辑。通过继承该类,可以实现具体类型对象的创建和回收方法。将这部分逻辑抽象到 Recycler 中的好处是可以灵活地扩展和定制对象的创建和回收行为。

设计的好处和意义:

  • 模块化和可扩展性: 将对象池的不同职责划分到不同的接口和类中,使得每个部分都可以单独扩展或替换,增强了系统的模块化和可扩展性。

  • 解耦和复用: 将对象的创建、回收和池的管理分离,提高了代码的可维护性和复用性。例如,可以通过实现不同的 Recycler 子类来定制对象的创建和回收策略。

  • 灵活性: 通过使用 ObjectCreatorHandle 接口,使得对象的创建和回收可以被不同的实现灵活地处理,而不是硬编码在对象池中。

  • 对于特定逻辑的集中处理: 将对象创建和回收逻辑放在 Recycler 类中,使得这些逻辑能够集中处理,有利于代码的维护和理解。同时,RecyclerObjectPool 作为具体的对象池实现类,主要负责管理 Recycler 的使用,起到了组织和管理的作用。

总体来说,这种设计提供了更灵活、可扩展、可维护的对象池实现。大概……就是因为好拓展罢了,反正我觉得并不利于理解


  1. 可以预见的是这个系列估计要很长了…… ↩︎

  2. 其实也不见得是有什么好处,你想想你迭代的过程中,不是写的写的逻辑就成这样了,最后也能跑就懒得再优化,写框架的大牛也不见得所有设计都是 100% 优雅 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/336584.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三代量子计算机交付,中国芯片开辟新道路,光刻机难挡中国芯

日前安徽本源量子宣布第三代超导量子计算系统正式上线&#xff0c;这是中国最先进的量子计算机&#xff0c;计算量子比特已达到72个&#xff0c;在全球已居于较为领先的水平&#xff0c;这对于中国芯片在原来的硅基芯片受到光刻机阻碍无疑是巨大的鼓舞。 据悉本源量子的第一代、…

欢乐的周末 - 华为OD统一考试

OD统一考试 题解&#xff1a; Java / Python / C 题目描述 小华和小为是很要好的朋友&#xff0c;他们约定周末一起吃饭。 通过手机交流&#xff0c;他们在地图上选择了多个聚餐地点(由于自然地形等原因&#xff0c;部分聚餐地点不可达)。求小华和小为都能到达的聚餐地点有多…

LED电子屏组装常见故障及解决办法大全

在LED电子屏的组装过程中&#xff0c;可能会遇到各种故障。以下是一些常见问题及其解决方法&#xff1a; 1. 加载不上可能的原因及解决办法&#xff1a; A. 确保控制系统硬件正确上电&#xff08;5V&#xff09;。 B. 检查并确认用于连接控制器的串口线为直通线。 C. 检查串口…

【Android 10】应用全屏

应用全屏 1.在theme.xml新建style继承Theme.Material3.DayNight.NoActionBar&#xff08;或者其他&#xff09;&#xff0c;添加<item name"android:windowFullscreen">true</item> <style name"Base.Theme.SIM" parent"Theme.Materi…

通过 Elastic Stack 充分利用电信领域生成式 AI 的力量

作者&#xff1a;Elastic Piotr Kobziakowski, Jrgen Obermann 在瞬息万变的电信领域&#xff0c;Elastic Stack 与生成式 AI 的集成正在开创运营效率和创新的新时代。 这些技术不仅增强了网络运营&#xff0c;而且还彻底改变了各个部门的内部流程。 下面&#xff0c;我们将深入…

求阶乘(优化版)

✨欢迎来到脑子不好的小菜鸟的文章✨ &#x1f388;创作不易&#xff0c;麻烦点点赞哦&#x1f388; 所属专栏&#xff1a;刷题 我的主页&#xff1a;脑子不好的小菜鸟 文章特点&#xff1a;关键点和步骤讲解放在 代码相应位置 明天考试&#xff0c;今天复习&#xff0c;复习…

echarts——折线图实现不同区间不同颜色+下钻/回钻功能——技能提升

echarts——折线图实现不同区间不同颜色下钻/回钻功能——技能提升 需求场景解决步骤1&#xff1a;安装echarts插件解决步骤2&#xff1a;html代码解决步骤3&#xff1a;封装option配置和initChart渲染方法解决步骤4&#xff1a;回钻功能 需求场景 最近在写后台管理系统时&…

数据结构第十二弹---堆的应用

堆的应用 1、堆排序2、TopK问题3、堆的相关习题总结 1、堆排序 要学习堆排序&#xff0c;首先要学习堆的向下调整算法&#xff0c;因为要用堆排序&#xff0c;你首先得建堆&#xff0c;而建堆需要执行多次堆的向下调整算法。 但是&#xff0c;使用向下调整算法需要满足一个前提…

第六讲_css盒子模式

css盒子模型 1. 长度单位2. 盒子模型的组成2.1 盒子模型内容2.2 盒子模型内边距2.3 盒子模型边框2.4 盒子模型外边距 1. 长度单位 px&#xff1a;像素em&#xff1a;相对于当前元素或父元素的 font-size 的倍数 <style>.parent {height: 500px;width: 500px;background…

将Django项目从本地上传至宝塔服务器(踩坑记录)

文章目录 写在前面配置本地文件配置宝塔面板解决遇到问题展示运行结果热门文章 自我介绍 ⭐2022年度CSDN 社区之星 Top6 ⭐2023年度CSDN 博客之星 Top16 ⭐2023年度CSDN 城市之星 Top2&#xff08;苏州&#xff09; ⭐CSDN Python领域 优质创作者 ⭐CSDN 内容合伙人 推荐热门…

Three.js如何设置旋转轴心【PIVOT】

在使用Three.js开发3D应用时&#xff0c;经常碰到的一个问题就是如何自定义模型的旋转轴心&#xff08;pivot&#xff09;。例如下面的立方体&#xff0c;假设建模时的轴心在立方体的中心&#xff0c;但是如果希望立方体绕着某个指定的点旋转&#xff08;例如图中标红的顶点&am…

结构型设计模式——适配器模式

适配器模式 这个更加好理解&#xff0c;就是做适配功能的类&#xff0c;例如&#xff0c;现在手机没有了圆形耳机接口&#xff0c;只有Type-C接口&#xff0c;因此你如果还想要使用圆形耳机的话需要买个圆形接口转Type-C的转换器&#xff08;适配器&#xff09;&#xff0c;这…