在上一篇文章中,已经比较清晰的介绍了对象池的概念也抽象了一套对象池的模板IPool,并且根据抽象的模板我们还实现了GameObject的对象池GameObjectPool。
这一篇文章我们要实现Class类的对象池,当然还是基于对象池模板IPool。
所以如果没看过第一篇文章,建议先去看一下。传送门
为什么要专门写一篇文章来写Class的对象池呢?
因为它很常用也很重要!众所周知,C#是一门面向对象的编程语言,在C#的世界里一切都是对象,在我们开发中通常需要抽象出很多的对象,例如 子弹对象、枪对象、小车对象、敌人对象…。其实说白了,这些对象就是一个个的Class当然也可能是struct这里以Class为例,有些对象的生命周期很短但是却要重复的创建,这个时候如果没有一套对象池的机制,对程序无疑是一种负担,在上一篇文章我们也讲了,对内存对CPU都是一种沉重的负担。
根据上一篇文章我们知道,继承IPool处理一种特定类型的对象是非常容易的,
如下所示,我们创建一个class A 并规定A在回收时和销毁时应该怎么做,然后我们创建了A的对象池APool
public class A
{
//数据重置
public void Reset(object userData)
{
}
//回收时
public void OnRecycle()
{
}
//销毁时
public void OnDestroy()
{
}
}
public class APool : IPool<A>
{
protected override A OnCreateItem()
{
return new A();
}
protected override void OnGetBefore(A item, object userData)
{
item.Reset(userData);
}
protected override void OnRecycle(A item)
{
item.OnRecycle();
}
protected override void OnDestroyItem(A item)
{
item.OnDestroy();
}
}
因为有模板所以我们很容易就实现了A对象的对象池,但是如果后期我们还有B、C、D、E等很多的对象都需要对象池,那我们总不能把BPool、CPool、DPool、EPool等对象池挨个都实现一遍吧,这个工作量可是不小,这个时候我们下意识的会想到抽象,既然对象不具体那就抽象呗。
那该怎么抽想呢?首先要回收的对象肯定不能写的很具体,它肯定需要抽象。但是对象如果我们用泛型进行抽象了又怎么保证在对象回收、创建和销毁时执行对的事情呢?是不是应该定义一个接口来规范需要回收的对象在合适的时机做合适的事情。
所以我们先定义需要回收的对象的接口,如下:
public interface IScriptPoolItem
{
/// <summary>
/// 数据重置
/// </summary>
/// <param name="userData">用户数据</param>
void Reset(object userData=null);
/// <summary>
/// 回收时触发
/// </summary>
void OnRecycle();
/// <summary>
/// 销毁时触发
/// </summary>
void OnDestroy();
}
然后再实现抽象对象的对象池:
public class ScriptPool<T> : IPool<T> where T:IScriptPoolItem,new()
{
protected override T OnCreateItem()
{
return new T();
}
protected override void OnGetBefore(T item, object userData)
{
item.Reset(userData);
}
protected override void OnRecycle(T item)
{
item.OnRecycle();
}
protected override void OnDestroyItem(T item)
{
item.OnDestroy();
}
}
OK 基本就是这样,一个通用的Class对象池就做好了
那如果再次实现A的对象池就可以这样写:
//创建A对象的对象池
ScriptPool<A> aPool = new ScriptPool<A>();
//从对象池取出或创建一个A
A a = aPool.Get();
//把对象A回收了
aPool.Recycle(a);
public class A:IScriptPoolItem
{
public void Reset(object userData)
{
}
public void OnRecycle()
{
}
public void OnDestroy()
{
}
}
如果有对象B、C、D、E等,只需要对象继承IScriptPoolItem接口就可以直接用ScriptPool来进行管理了。