Шаблоны проектирования — это фундаментальные решения распространенных проблем, возникающих при разработке программного обеспечения. Они предоставляют многократно используемые шаблоны и рекомендации по созданию гибкого и удобного в сопровождении кода. В этой статье мы рассмотрим различные категории шаблонов проектирования и приведем примеры кода для каждой категории.
Категории шаблонов проектирования.
Шаблоны проектирования можно разделить на три основные категории в зависимости от их назначения и области применения: шаблоны создания, структурные шаблоны и поведенческие шаблоны.
- Шаблоны создания.
Шаблоны создания сосредоточены на механизмах создания объектов, обеспечивая гибкость при создании объектов и одновременно способствуя слабой связи между классами. Некоторые часто используемые творческие шаблоны:
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
- Структурные шаблоны.
Структурные шаблоны связаны с композицией классов и объектов, уделяя особое внимание связям между ними. Они помогают создавать крупномасштабные системы, предоставляя гибкие структуры классов и объектов. Некоторые часто используемые структурные шаблоны:
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
- Поведенческие шаблоны.
Поведенческие шаблоны сосредоточены на общении и взаимодействии между объектами, определяя шаблоны взаимодействия для повышения гибкости и удобства обслуживания. Некоторые часто используемые модели поведения:
а. Выкройка наблюдателя:
Шаблон 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. Понимая и применяя эти шаблоны, разработчики могут улучшить качество, гибкость и расширяемость своего программного обеспечения.