Skip to content

Урок 7.3. Flyweight на Java

Шаблон проектирования "Легковес" (Flyweight) используется для уменьшения потребления памяти, когда необходимо создать большое количество объектов, которые имеют общие состояния. Этот паттерн позволяет разделять и повторно использовать объекты, что особенно полезно в ситуациях, когда объекты имеют много одинаковых данных.

Пример использования паттерна Flyweight на Java

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

Шаг 1: Создание интерфейса

public interface Tree {
    void draw(int x, int y);
}

Шаг 2: Реализация конкретного легковесного объекта

public class TreeType implements Tree {
    private String type;
    private String color;

    public TreeType(String type, String color) {
        this.type = type;
        this.color = color;
    }

    @Override
    public void draw(int x, int y) {
        System.out.println("Drawing a " + color + " " + type + " tree at (" + x + ", " + y + ")");
    }
}

Шаг 3: Создание фабрики легковесов

import java.util.HashMap;
import java.util.Map;

public class TreeFactory {
    private Map<String, Tree> treeTypes = new HashMap<>();

    public Tree getTreeType(String type, String color) {
        String key = type + ":" + color;
        if (!treeTypes.containsKey(key)) {
            treeTypes.put(key, new TreeType(type, color));
        }
        return treeTypes.get(key);
    }
}

Шаг 4: Использование легковесов

Теперь мы можем использовать наш легковес в коде:

import java.util.ArrayList;
import java.util.List;

public class FlyweightPatternDemo {
    public static void main(String[] args) {
        TreeFactory treeFactory = new TreeFactory();
        List<Tree> forest = new ArrayList<>();

        // Создаем деревья
        forest.add(treeFactory.getTreeType("Oak", "Green"));
        forest.add(treeFactory.getTreeType("Pine", "Dark Green"));
        forest.add(treeFactory.getTreeType("Birch", "White"));

        // Рисуем деревья в разных местах
        for (int i = 0; i < 10; i++) {
            forest.get(i % 3).draw(i * 10, i * 5);
        }
    }
}

Объяснение

  1. Интерфейс Tree: Определяет метод draw(), который будет реализован конкретными легковесами.

  2. Класс TreeType: Реализует интерфейс Tree. Он содержит общие характеристики дерева, такие как тип и цвет, и реализует метод draw(), который выводит информацию о дереве.

  3. Класс TreeFactory: Фабрика, которая управляет созданием и хранением легковесов. Она использует HashMap для хранения уже созданных объектов TreeType, чтобы избежать дублирования.

  4. Класс FlyweightPatternDemo: Демонстрирует использование паттерна "Легковес". Мы создаем несколько деревьев с общими характеристиками и рисуем их в разных местах, используя один и тот же объект для каждого типа дерева.

Заключение

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