Демонстрация паттерна Object Pool (Пул объектов) на примере системы частиц для консольной игры.
Пул объектов — это порождающий паттерн проектирования, который позволяет переиспользовать объекты вместо их постоянного создания и уничтожения. Это особенно важно в игровой разработке, где:
- Частицы, снаряды, враги создаются и удаляются сотнями в секунду
- Частое выделение памяти приводит к нагрузке на сборщик мусора (GC)
- Производительность игры может значительно снизиться
В этом проекте реализован пул для объектов Particle, которые могут использоваться многократно.
ObjectPool/
├── Program.cs # Демонстрация работы пула
└── README.md # Этот файл
| Класс | Описание |
|---|---|
Particle |
Объект частицы: координаты, символ, цвет, время жизни |
ParticlePool |
Пул объектов: выдача и возврат частиц с автоматическим расширением |
// Создаем пул на 5 частиц
ParticlePool pool = new ParticlePool(5);
// Получаем частицу из пула
Particle particle = pool.Get();
particle.X = 10;
particle.Y = 5;
particle.Symbol = '*';
particle.Color = ConsoleColor.Red;
particle.Lifetime = 3;
// ... использование частицы ...
// Возвращаем в пул для переиспользования
pool.Return(particle);В Main() симулируется игровой цикл:
- Создается пул на 5 частиц
- Выстреливается 10 частиц (первые 5 создаются, следующие 5 переиспользуются)
- Частицы живут случайное количество кадров (3–10)
- После "смерти" возвращаются в пул
- На 6-м кадре происходит новый выстрел — новые частицы берутся из пула
- Автоматическое расширение — если пул пуст, новая частица создается автоматически
- Сброс состояния — при возврате в пул частица очищается через
Reset() - LIFO (
Stack) — используется стек для хранения свободных объектов, что дает лучшую локальность кэша - Безопасность — пул не принимает
nullи корректно обрабатывает возврат
В реализации используется Stack<Particle> (LIFO).
Это дает небольшое преимущество: последний использованный объект с большей вероятностью еще "горячий" в кэше процессора, что улучшает производительность при частых операциях Get/Return.
Для большинства случаев разница незаметна, и Queue (FIFO) также подошел бы.
- Паттерн
Object Pool - Управление памятью и производительностью
- Работа с
Stack<T>и обобщениями (generics) - Сброс состояния объектов перед переиспользованием
Vladimir Vaize | GitHub | Telegram Channel