Ответ
Структурные паттерны проектирования помогают организовать классы и объекты в более крупные структуры, сохраняя гибкость, эффективность и упрощая взаимодействие между компонентами. Они описывают, как объекты и классы могут быть скомпонованы для формирования больших структур.
Основные структурные паттерны:
-
Адаптер (Adapter)
- Что делает: Преобразует интерфейс одного класса в другой интерфейс, ожидаемый клиентом, позволяя классам с несовместимыми интерфейсами работать вместе.
- Когда использовать: Когда нужно интегрировать существующий класс, который имеет неподходящий интерфейс, в новую систему.
- Пример:
# Несовместимый класс class OldSystem: def old_request(self): return "Data from Old System"
Ожидаемый интерфейс
class NewSystemTarget: def request(self): pass
Адаптер
class Adapter(NewSystemTarget): def init(self, old_system_instance): self._old_system = old_system_instance
def request(self): return f"Adapter: {self._old_system.old_request()}"
Использование
old_obj = OldSystem() adapter = Adapter(old_obj) print(adapter.request()) # Adapter: Data from Old System
-
Декоратор (Decorator)
- Что делает: Динамически добавляет объекту новую функциональность, оборачивая его в объект-декоратор. Это гибкая альтернатива наследованию для расширения функционала.
- Когда использовать: Когда нужно добавить или удалить обязанности объекта во время выполнения, не изменяя его структуру.
- Пример:
class Coffee: def get_cost(self): return 5 def get_ingredients(self): return "Coffee"
class MilkDecorator: def init(self, coffee): self._coffee = coffee def get_cost(self): return self._coffee.get_cost() + 2 def get_ingredients(self): return self._coffee.get_ingredients() + ", Milk"
my_coffee = Coffee() my_coffee = MilkDecorator(my_coffee) print(f"Cost: {my_coffee.get_cost()}, Ingredients: {my_coffee.get_ingredients()}")
Cost: 7, Ingredients: Coffee, Milk
-
Фасад (Facade)
- Что делает: Предоставляет унифицированный (упрощенный) интерфейс к сложной подсистеме, скрывая ее сложность.
- Когда использовать: Когда система состоит из множества взаимосвязанных классов, и нужно предоставить простой способ взаимодействия с ней.
-
Компоновщик (Composite)
- Что делает: Позволяет группировать объекты в древовидные структуры и работать с ними как с отдельными объектами. Клиент может единообразно обращаться как к отдельным объектам, так и к их группам.
- Когда использовать: Когда нужно представить иерархию объектов "часть-целое" и позволить клиентам игнорировать разницу между отдельными объектами и их композициями.
-
Заместитель (Proxy)
- Что делает: Предоставляет суррогат или заполнитель для другого объекта, контролируя доступ к нему. Это позволяет добавить дополнительную логику (например, ленивую инициализацию, кэширование, контроль доступа) перед доступом к реальному объекту.
- Когда использовать: Когда нужен более контролируемый или отложенный доступ к объекту.
-
Мост (Bridge)
- Что делает: Разделяет абстракцию и реализацию, позволяя им изменяться независимо друг от друга. Это достигается путем вынесения реализации в отдельную иерархию.
- Когда использовать: Когда нужно избежать постоянной привязки абстракции к ее реализации или когда и абстракция, и реализация должны расширяться независимо.
-
Приспособленец (Flyweight)
- Что делает: Экономит память, разделяя общее состояние между множеством объектов. Используется, когда большое количество мелких объектов имеет много общего состояния.
- Когда использовать: Когда приложение должно поддерживать большое количество объектов, и их создание или хранение становится слишком затратным по памяти.