Структурный шаблон программирования Приспособленец (Flyweight)

«Приспособленец» (Flyweight) является одним из основных структурных шаблонов проектирования, предназначенным для экономии памяти путём совместного использования общих состояний объектов. Этот шаблон особенно эффективен в тех случаях, когда в приложении присутствует большое количество похожих объектов, многие из которых содержат повторяющиеся данные.


Цель и назначение

Основная задача «Приспособленца» — уменьшить потребление оперативной памяти за счёт повторного использования общего состояния множества мелких объектов. Вместо того чтобы создавать отдельные объекты для каждого экземпляра, шаблон создаёт один общий экземпляр и повторно использует его там, где возможно.

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


Принцип работы

Ключевое различие между внутренним состоянием и внешним состоянием:

  • Внутреннее состояние: Данные, общие для нескольких экземпляров (обычно неизменяемые).
  • Внешнее состояние: Индивидуальные характеристики конкретного объекта, отличающие его от остальных (часто изменяемые).

Алгоритм действий:

  1. Все общие данные (внутреннее состояние) извлекаются из отдельных объектов и сохраняются централизованно.
  2. Объекты сохраняют лишь внешнее состояние, специфичное именно для них.
  3. Когда внешний клиент запрашивает операцию над объектом, приспособленец получает необходимые внешние данные и применяет свою общую логику обработки.

Преимущества и недостатки

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

  • Значительное снижение потребления памяти за счёт минимизации дублирования.
  • Улучшается масштабируемость приложения при большом количестве однотипных объектов.
  • Простота поддержки и сопровождения программы благодаря стандартизированному способу хранения общедоступных данных.

Недостатки:

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

Пример реализации на PHP

Рассмотрим простой пример реализации шаблона «Приспособленец». Представьте себе редактор документов, где символы представлены отдельными объектами. Мы хотим минимизировать память, создав единый набор приспособленцев для символов.

Шаг 1: Объявляем класс Symbol (символ)

abstract class Symbol {
    abstract public function render(string $context): string;
}

Шаг 2: Конкретные классы символов

class LetterSymbol extends Symbol {
    protected $letter;

    public function __construct(string $letter) {
        $this->letter = $letter;
    }

    public function render(string $context): string {
        return $context . $this->letter;
    }
}

class PunctuationSymbol extends Symbol {
    protected $punctuation;

    public function __construct(string $punctuation) {
        $this->punctuation = $punctuation;
    }

    public function render(string $context): string {
        return $context . $this->punctuation;
    }
}

Шаг 3: Класс FlyweightFactory (фабрика приспособленцев)

class FlyweightFactory {
    private static $symbols = [];

    public static function getSymbol(string $symbolType, string $value): Symbol {
        if (!isset(self::$symbols[$symbolType])) {
            switch ($symbolType) {
                case 'letter':
                    self::$symbols['letter'] = new LetterSymbol($value);
                    break;
                case 'punctuation':
                    self::$symbols['punctuation'] = new PunctuationSymbol($value);
                    break;
            }
        }
        return self::$symbols[$symbolType];
    }
}

Шаг 4: Используем фабрику приспособленцев

// Создание документа с использованием приспособленцев
$document = '';
for ($i = 0; $i < 10; ++$i) {
    $letter = FlyweightFactory::getSymbol('letter', 'A');
    $document .= $letter->render('');

    $comma = FlyweightFactory::getSymbol('punctuation', ',');
    $document .= $comma->render('');
}

echo $document; // A,A,A,A,A,A,A,A,A,

Заключение

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

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *