PassFront
  1. PassFront
  2. База знаний
  3. Структурные паттерны

Что такое Flyweight и как он экономит память?

Структурные паттерны

Flyweight делит состояние объекта на внутреннее (общее, неизменяемое) и внешнее (уникальное) и хранит общую часть в одном экземпляре на все объекты, которые её используют.

Как экономит

  • Карта с 1 000 000 деревьев: если каждое хранит свою текстуру (~1 КБ) и координаты, выходит ~1 ГБ.
  • Выносим текстуру, цвет и название вида в TreeType. Видов 10 — значит, 10 тяжёлых объектов, а дерево хранит только x, y и ссылку: порядок десятков мегабайт.
  • Фабрика кэширует разделяемые объекты по ключу в Map<string, TreeType> и никогда не создаёт дубль.

Условия применимости

  • Объектов действительно очень много, и у них большая повторяющаяся часть.
  • Внутреннее состояние неизменяемо, иначе правка одного «дерева» заденет все.
  • Внешнее состояние передаётся в методы (draw(ctx, x, y)) или хранится в контейнере-владельце.

Где встречается

  • Интернирование строк в JVM и V8, кэш Integer.valueOf для диапазона −128…127.
  • Глифы в текстовых редакторах: символ «а» с данными шрифта — один объект, позиции хранятся отдельно.
  • Скрытые классы V8: объекты с одинаковой формой делят описание раскладки свойств.

Цена

Код усложняется разделением состояния, а поиск во фабрике и передача внешних данных тратят CPU — выигрыш есть только при реальном давлении на память.

Коротко для собеседования

Flyweight выносит повторяющиеся неизменяемые данные в общие объекты из фабрики-кэша, а уникальные поля хранит отдельно или передаёт в методы. Имеет смысл только при миллионах похожих объектов и реальном давлении на память, иначе лишь усложняет код.

Другие вопросы раздела