«1. Обзор

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

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

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

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

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

Основными элементами шаблона являются:

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

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

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

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

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

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

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

private Engine engine;
private Color color;

2.3. Vehicle Factory

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

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

private static Map<Color, Vehicle> 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. Сжатие данных

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

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

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

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

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

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

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

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