Шаблон “object pool”
Категория
Порождающий
Описание
набор инициализированных и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула. Когда объект больше не нужен, он не уничтожается, а возвращается в пул.
Уместность применения
Объектный пул применяется для повышения производительности, когда создание объекта в начале работы и уничтожение его в конце приводит к большим затратам. Особенно заметно повышение производительности, когда объекты часто создаются-уничтожаются, но одновременно существует лишь небольшое их число.
Преимущества
1) Быстрый доступ к объектам. Экономия затрат памяти.
Недостатки
1) При росте числа объектов в пуле возможно переполнение
2)Неэффективно, если в системе много объектов которые часто используются
Реализация
public interface IPoolable
{
void releaseState();
}
public interface IPoolObjectCreator<T>
{
T Create();
}
public class ObjectPool<T> where T : class, IPoolable
{
private readonly ConcurrentBag<T> mContainer = new ConcurrentBag<T>();
private readonly IPoolObjectCreator<T> mCreator;
public int Count { get { return mContainer.Count; } }
public ObjectPool(IPoolObjectCreator<T> creator)
{
if (creator == null)
{
throw new ArgumentNullException("creator can't be null");
}
mCreator = creator;
}
public T GetObject()
{
T obj;
if (mContainer.TryTake(out obj))
{
return obj;
}
return mCreator.Create();
}
public void ReturnObject (ref T obj)
{
obj.releaseState();
mContainer.Add(obj);
obj = null;
}
}
public class ObjectCreatorImpl<T> : IPoolObjectCreator<T> where T : class, new()
{
T IPoolObjectCreator<T>.Create()
{
return new T();
}
}
static void Main(string[] args)
{
ObjectPool<TestObject> pool = new ObjectPool<TestObject>(new ObjectCreatorImpl<TestObject>());
Console.WriteLine("1) Using 'new' keyword ...");
for (int i = 0; i < 10; i++)
{
TestObject obj = new TestObject();
// Do something with the test object
obj.Index = i;
}
Console.WriteLine("2) Using Object pool ...");
for (int i = 0; i < 10; i++)
{
TestObject obj = pool.GetObject();
// Do something with the test object
obj.Index = i;
pool.ReturnObject(ref obj);
}
Console.ReadLine();
}