Найти тему

Паттерн "Легковес"

Оглавление

Давайте представим, что у нас есть приложение с котиками. Каждый котик имеет имя, возраст, породу и любимую игрушку. В обычном подходе мы бы создали отдельный объект для каждого котика со всеми этими характеристиками. Но что если у многих котиков одна и та же любимая игрушка? Правда нужно создавать новую игрушку каждый раз, даже если у другого котика она такая же? Здесь на помощь приходит паттерн Легковес.

Пример кода: https://github.com/Ladgertha/patterns/commit/fd784b8a7ff2811de2343b237a073967cfc15550

У нас есть котик:

Мы вынесли игрушку в отдельный класс, потому что у многих котиков может быть одинаковая игрушка.

-2

И сделали фабрику для игрушек:

-3

Теперь вместо того чтобы создавать новую игрушку для каждого котика, мы используем ToyFactory, которая возвращает существующую игрушку, если она уже была создана. Таким образом экономится память.

-4

Как видите, сам паттерн достаточно легкий. Но у него тоже есть несколько интересных аспектов, которые могут быть полезными:

  1. Кэширование: это одна из ключевых особенностей паттерна — использование кэширования для уменьшения количества создаваемых объектов.
  2. Иммутабельность: легковесные объекты обычно делаются неизменяемыми, чтобы после их создания их состояние не изменялось. Это упрощает управление ресурсами и обеспечивает безопасность при многопоточном доступе.
  3. Применение в графических интерфейсах: паттерн часто используется в UI. Это позволяет значительно уменьшить расход памяти. Как пример: в какой-нибудь игре, где множество оружия, мы можем использовать паттерн, а не создавать каждый раз новый объект оружия.
  4. Разделение состояния на внутреннее и внешнее: паттерн разделяет состояние объекта на "внутреннее" (неизменяемое, общее для всех объектов) и "внешнее" (изменяемое, уникальное для каждого объекта). Внутреннее состояние и является тем, что кэшируется и совместно используется (наша игрушка у кота — внутреннее состояние, а имя котика — внешнее).
  5. В Android уже есть примеры использования паттерна Легковес. Например, метод valueOf() в Integer и Boolean, использует предварительно созданные объекты, чтобы избежать ненужного создания новых экземпляров.
  6. Оптимизация производительности: в ситуациях, когда производительность критична, таких как рендеринг сложных сцен в играх, Легковес может использоваться для уменьшения затрат на отрисовку и обработку большого количества похожих объектов. Выше я как раз приводила пример с оружием в игре.
  7. Совместное использование объектов: цель паттерна Легковес — уменьшить количество объектов, создаваемых и хранящихся в памяти. Для этого он использует совместное использование объектов там, где это возможно. Например, наши котики совместно используют мячик.

Преимущества:

  1. Экономия памяти: повторное использование уже существующих объектов снижает потребление памяти.
  2. Быстродействие: уменьшение общего количества объектов улучшает производительность приложения

Недостатки:

  1. Сложность кода: введение паттерна увеличивает сложность кода. Но замечу, что не сильно усложняет. Видели мы паттерны, которые гораздо сложнее и состоят из десятка классов.
  2. Компромисс между памятью и временем выполнения: иногда экономия памяти может увеличить время доступа к данным.

Где использовать?

  • В приложениях, где нужно обрабатывать большое количество похожих объектов с общими характеристиками.
  • В случаях, когда экономия памяти может значительно повлиять на производительность, например, в играх или графических приложениях.
-5

Дубль статей в телеграмме — https://t.me/android_junior

Мои заметки в телеграмме — https://t.me/android_junior_notes

P.S. сделано с помощью ChatGPT и Midjourney. :)