Назад к вопросам
Middle+
72
questionbank

Что такое паттерн проектирования 'Приспособленец' (Flyweight)?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

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

Паттерн разделяет состояние объекта на две части:

  1. Внутреннее состояние (Intrinsic State): Состояние, общее для всех объектов и не зависящее от их контекста. Оно хранится внутри Приспособленца и разделяется между многими клиентами.
  2. Внешнее состояние (Extrinsic State): Состояние, зависящее от контекста использования объекта. Оно передаётся клиентом в методы Приспособленца по мере необходимости.

Основные компоненты паттерна:

  • Flyweight (Приспособленец): Интерфейс или абстрактный класс, объявляющий методы, которые принимают внешнее состояние в качестве параметра.
  • ConcreteFlyweight (Конкретный Приспособленец): Класс, реализующий интерфейс Flyweight и хранящий внутреннее состояние.
  • FlyweightFactory (Фабрика Приспособленцев): Класс, управляющий созданием и кешированием объектов ConcreteFlyweight. Он проверяет, существует ли уже Приспособленец с заданным внутренним состоянием, и возвращает его, либо создает новый.
  • Client (Клиент): Объект, использующий Приспособленцев, который хранит внешнее состояние и вызывает методы Приспособленцев, передавая это состояние.

Пример использования: текстовый редактор. Символы (буквы, цифры) могут быть Приспособленцами. Внутреннее состояние символа - это сам символ (например, 'A'). Внешнее состояние - это его позиция, цвет, размер шрифта. Вместо создания нового объекта для каждого символа в документе, создается только один объект для каждого уникального символа, и его характеристики форматирования применяются "извне".

import json // Пример импорта, хотя в данном коде не используется

// Интерфейс Приспособленца
class Flyweight:
    def operation(self, extrinsic_state): // Метод, принимающий внешнее состояние
        pass

// Конкретный Приспособленец
class ConcreteFlyweight(Flyweight):
    def __init__(self, intrinsic_state):
        self._intrinsic_state = intrinsic_state // Внутреннее состояние

    def operation(self, extrinsic_state):
        # Симуляция выполнения операции с учетом внешнего состояния
        print(f"ConcreteFlyweight: Intrinsic state - {self._intrinsic_state}, Extrinsic state - {extrinsic_state}")

// Фабрика Приспособленцев
class FlyweightFactory:
    _flyweights = {} // Кеш Приспособленцев

    def get_flyweight(self, intrinsic_state):
        if intrinsic_state not in self._flyweights:
            print(f"FlyweightFactory: Creating a new flyweight for {intrinsic_state}")
            self._flyweights[intrinsic_state] = ConcreteFlyweight(intrinsic_state) # Создание нового Приспособленца
        else:
            print(f"FlyweightFactory: Reusing existing flyweight for {intrinsic_state}")
        return self._flyweights[intrinsic_state] // Возвращение существующего или нового Приспособленца

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

  • Сокращение потребления памяти благодаря разделению общего состояния.
  • Уменьшение количества создаваемых объектов.

Недостатки:

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