Рубрики
Без рубрики

Шаблон Flyweight на Java

Краткое и практическое введение в принципы построения модели летного веса.

Автор оригинала: Donato Rimenti.

1. Обзор

В этой статье мы рассмотрим шаблон дизайна мушки. Этот шаблон используется для уменьшения объема памяти. Это также может повысить производительность в приложениях, где создание экземпляров объектов обходится дорого.

Проще говоря, шаблон flyweight основан на фабрике, которая перерабатывает созданные объекты, сохраняя их после создания. Каждый раз, когда запрашивается объект, фабрика ищет объект, чтобы проверить, был ли он уже создан. Если это так, возвращается существующий объект – в противном случае создается, сохраняется и затем возвращается новый.

Состояние объекта flyweight состоит из инвариантного компонента, совместно используемого с другими аналогичными объектами ( внутренний ), и компонента варианта, которым может управлять клиентский код ( внешний ).

Очень важно, чтобы объекты flyweight были неизменяемыми: любая операция по состоянию должна выполняться заводом.

2. Реализация

Основными элементами рисунка являются:

  • интерфейс, определяющий операции, которые клиентский код может выполнять с объектом flyweight
  • одна или несколько конкретных реализаций нашего интерфейса
  • фабрика для обработки создания экземпляров объектов и кэширования

Давайте посмотрим, как реализовать каждый компонент.

2.1. Интерфейс транспортного средства

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

public void start();
public void stop();
public Color getColor();

2.2. Бетонное транспортное средство

Далее, давайте создадим Автомобиль класс в качестве конкретного транспортного средства. Наш автомобиль будет реализовывать все методы интерфейса транспортного средства. Что касается его состояния, у него будет движок и цветовое поле:

private Engine engine;
private Color color;

2.3. Автомобильный завод

И последнее, но не менее важное: мы создадим Автомобильный завод . Создание нового автомобиля – очень дорогостоящая операция, поэтому завод будет создавать только один автомобиль каждого цвета.

Для этого мы отслеживаем созданные транспортные средства, используя карту в качестве простого кэша:

private static Map vehiclesCache
  = new HashMap<>();

public static Vehicle createVehicle(Color color) {
    Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> { 
        Engine newEngine = new Engine();
        return new Car(newEngine, newColor);
    });
    return newVehicle;
}

Обратите внимание, что клиентский код может влиять только на внешнее состояние объекта (цвет нашего транспортного средства), передавая его в качестве аргумента методу createVehicle .

3. Примеры использования

3.1. Сжатие Данных

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

Классический пример такого использования-текстовый процессор. Здесь каждый символ является объектом flyweight, который делится данными, необходимыми для рендеринга. В результате только положение символа внутри документа занимает дополнительную память.

3.2. Кэширование Данных

Многие современные приложения используют кэши для увеличения времени отклика. Шаблон flyweight аналогичен основной концепции кэша и может хорошо соответствовать этой цели.

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

4. Заключение

Подводя итог, этот краткий учебник был посвящен шаблону проектирования flyweight в Java. Мы также проверили некоторые из наиболее распространенных сценариев, связанных с этим шаблоном.

Весь код из примеров доступен в проекте GitHub .