Введение
Шаблон проектирования программного обеспечения для объектов
В компьютерном программировании шаблон проектирования "Легковес" (Flyweight) относится к объекту, который минимизирует использование памяти за счет совместного использования части своих данных с другими похожими объектами. Шаблон "Легковес" является одним из двадцати трех известных шаблонов проектирования GoF. Эти шаблоны способствуют созданию гибкого объектно-ориентированного дизайна программного обеспечения, которое легче реализовать, изменять, тестировать и повторно использовать. В других контекстах идея совместного использования структур данных называется хэш-консингом. Термин был впервые введен, а идея всесторонне исследована Полом Кальдером и Марком Линтоном в 1990 году для эффективной обработки информации о глифах в редакторе документов WYSIWYG. Однако аналогичные методы уже использовались в других системах, начиная с 1988 года.
Подробности реализации
Есть несколько способов реализации шаблона «лёгкий вес». Один из примеров — изменяемость: могут ли объекты, хранящие внешнее состояние, изменяться. Неизменяемые объекты легко передавать и совместно использовать, но при изменении состояния требуется создавать новые внешние объекты. В отличие от этого, изменяемые объекты могут совместно использовать состояние. Изменяемость позволяет лучше повторно использовать объекты за счёт кэширования и повторной инициализации старых, неиспользуемых объектов. Совместное использование обычно неэффективно, когда состояние сильно меняется. Другие важные аспекты включают в себя способ получения доступа к объекту «лёгкий вес» для конечного клиента, кэширование и обеспечение параллельного доступа.
Восстановление
Заводской интерфейс для создания или повторного использования легковесных объектов часто является фасадом для сложной базовой системы. Например, заводской интерфейс обычно реализуется как одиночка (singleton), чтобы обеспечить глобальный доступ к созданию легковесов. Как правило, алгоритм получения начинается с запроса нового объекта через заводской интерфейс. Запрос обычно перенаправляется в соответствующий кэш в зависимости от типа запрашиваемого объекта. Если запрос удовлетворяется объектом из кэша, он может быть повторно инициализирован и возвращен. В противном случае создается новый объект. Если объект состоит из нескольких внешних подкомпонентов, они собираются вместе перед возвратом объекта.
Кэширование
Существует два способа кэширования легковесных объектов: кэши с поддержкой и без поддержки. Объекты с сильно изменяемым состоянием можно кэшировать, используя структуру FIFO. Эта структура хранит неиспользуемые объекты в кэше, что исключает необходимость поиска по кэшу. В отличие от этого, кэши без поддержки имеют меньшие первоначальные накладные расходы: объекты для кэшей инициализируются оптом во время компиляции или запуска. После заполнения кэша объектами, алгоритм извлечения объектов может потребовать больших накладных расходов, чем операции push/pop в кэше с поддержкой. При извлечении внешних объектов с неизменяемым состоянием достаточно просто выполнить поиск в кэше объекта с нужным состоянием. Если такой объект не найден, необходимо инициализировать объект с этим состоянием. При извлечении внешних объектов с изменяемым состоянием, кэш должен быть просмотрен на предмет наличия неиспользуемого объекта для переинициализации, если не найден используемый объект. Если неиспользуемых объектов нет, необходимо создать новый объект и добавить его в кэш. Можно использовать отдельные кэши для каждого уникального подкласса внешних объектов. Несколько кэшей можно оптимизировать независимо друг от друга, связав с каждым кэшем уникальный алгоритм поиска. Эта система кэширования объектов может быть инкапсулирована с помощью шаблона "цепочка обязанностей", что способствует слабой связанности между компонентами.