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

2024-01-10 12:29:39

想了一下,我决定还是做更细化的拆解,也看了很多源码剖析的文章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>() {
                @Override
                protected T newObject(Handle<T> handle) {
                    return creator.newObject(handle);
                }
            };
        }

        @Override
        public 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% 优雅 ??

文章来源:https://blog.csdn.net/w903328615/article/details/135499018
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。