Полное руководство по шаблонам проектирования: изучение категорий и примеров кода

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

Категории шаблонов проектирования.
Шаблоны проектирования можно разделить на три основные категории в зависимости от их назначения и области применения: шаблоны создания, структурные шаблоны и поведенческие шаблоны.

  1. Шаблоны создания.
    Шаблоны создания сосредоточены на механизмах создания объектов, обеспечивая гибкость при создании объектов и одновременно способствуя слабой связи между классами. Некоторые часто используемые творческие шаблоны:
    a. Шаблон Singleton:
    Шаблон Singleton гарантирует, что во всем приложении существует только один экземпляр класса. Это полезно, когда вам нужна единая точка доступа к общему ресурсу.
class Singleton:
    _instance = None
    def __new__(cls, *args, kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, kwargs)
        return cls._instance

б. Шаблон «Фабрика»:
Шаблон «Фабрика» делегирует ответственность за создание экземпляров объектов фабричному классу. Он предоставляет интерфейс для создания объектов, позволяя клиентскому коду работать с интерфейсом вместо конкретных реализаций.

class Product:
    def display(self):
        pass
class ConcreteProductA(Product):
    def display(self):
        print("ConcreteProductA")
class ConcreteProductB(Product):
    def display(self):
        print("ConcreteProductB")
class ProductFactory:
    def create_product(self, product_type):
        if product_type == "A":
            return ConcreteProductA()
        elif product_type == "B":
            return ConcreteProductB()
        else:
            raise ValueError("Invalid product type")
factory = ProductFactory()
product = factory.create_product("A")
product.display()  # Output: ConcreteProductA
  1. Структурные шаблоны.
    Структурные шаблоны связаны с композицией классов и объектов, уделяя особое внимание связям между ними. Они помогают создавать крупномасштабные системы, предоставляя гибкие структуры классов и объектов. Некоторые часто используемые структурные шаблоны:
    a. Шаблон адаптера.
    Шаблон адаптера позволяет несовместимым классам работать вместе путем преобразования интерфейса одного класса в другой, ожидаемый клиентом.
class LegacySystem:
    def specific_operation(self):
        return "Legacy Operation"
class NewSystem:
    def operation(self):
        return "New Operation"
class LegacyToNewAdapter(NewSystem):
    def __init__(self, legacy_system):
        self.legacy_system = legacy_system
    def operation(self):
        return self.legacy_system.specific_operation()
legacy_system = LegacySystem()
adapter = LegacyToNewAdapter(legacy_system)
result = adapter.operation()  # Output: Legacy Operation

б. Шаблон «Декоратор»:
Шаблон «Декоратор» позволяет динамически добавлять новое поведение к объекту, не изменяя его структуру. Он представляет собой гибкую альтернативу созданию подклассов для расширения функциональности.

class Component:
    def operation(self):
        pass
class ConcreteComponent(Component):
    def operation(self):
        return "Original Operation"
class Decorator(Component):
    def __init__(self, component):
        self.component = component
    def operation(self):
        return self.component.operation()
class ConcreteDecorator(Decorator):
    def operation(self):
        return f"Decorated {self.component.operation()}"
component = ConcreteComponent()
decorated_component = ConcreteDecorator(component)
result = decorated_component.operation()  # Output: Decorated Original Operation
  1. Поведенческие шаблоны.
    Поведенческие шаблоны сосредоточены на общении и взаимодействии между объектами, определяя шаблоны взаимодействия для повышения гибкости и удобства обслуживания. Некоторые часто используемые модели поведения:
    а. Выкройка наблюдателя:
    Шаблон Observer определяет зависимость между объектами «один ко многим», позволяя получать уведомления нескольким наблюдателям при изменении состояния субъекта.
class Subject:
    def __init__(self):
        self.observers = []
    def attach(self, observer):
        self.observers.append(observer)
    def detach(self, observer):
        self.observers.remove(observer)
    def notify(self):
        for observer in self.observers:
            observer.update()
class Observer:
    def update(self):
        pass
class ConcreteObserver(Observer):
    def update(self):
        print("Observer notified")
subject = Subject()
observer = ConcreteObserver()
subject.attach(observer)
subject.notify()  # Output: Observer notified

б. Шаблон стратегии:
Шаблон стратегии определяет семейство взаимозаменяемых алгоритмов и инкапсулирует каждый из них, позволяя использовать их взаимозаменяемо. Это способствует слабой связи между клиентом и реализацией алгоритма.

class Strategy:
    def execute(self):
        pass
class ConcreteStrategyA(Strategy):
    def execute(self):
        print("Strategy A")
class ConcreteStrategyB(Strategy(Continued):
    def execute(self):
        print("Strategy B")
class Context:
    def __init__(self, strategy):
        self.strategy = strategy
    def execute_strategy(self):
        self.strategy.execute()
strategy_a = ConcreteStrategyA()
context = Context(strategy_a)
context.execute_strategy()  # Output: Strategy A

Шаблоны проектирования — это важные инструменты для разработчиков программного обеспечения, позволяющие создавать надежный и удобный в сопровождении код. В этой статье мы исследовали три основные категории шаблонов проектирования: творческие, структурные и поведенческие. Мы предоставили примеры кода для каждой категории, включая шаблоны Singleton, Factory, Adaptor, Decorator, Observer и Strategy. Понимая и применяя эти шаблоны, разработчики могут улучшить качество, гибкость и расширяемость своего программного обеспечения.