← Назад к вопросам
Приведи пример использования паттернов программирования
2.0 Middle🔥 151 комментариев
#Python Core#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры использования паттернов программирования
Я продемонстрирую практическое применение основных паттернов с реальными примерами.
1. Singleton (Одиночка)
Используется для единого объекта (конфиг, база данных, логгер):
import logging
from functools import lru_cache
# Паттерн Singleton через decorator
class DatabaseConnection:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._connection = None
return cls._instance
def connect(self, url):
if self._connection is None:
self._connection = f"Connected to {url}"
return self._connection
return self._connection
# Использование
db1 = DatabaseConnection()
db2 = DatabaseConnection()
assert db1 is db2 # Один и тот же объект
db1.connect("postgres://localhost")
print(db2._connection) # Данные доступны
2. Factory (Фабрика)
Создание объектов без привязки к их конкретным классам:
from abc import ABC, abstractmethod
class Payment(ABC):
@abstractmethod
def pay(self, amount):
pass
class CreditCardPayment(Payment):
def pay(self, amount):
return f"Оплачено {amount}р кредитной картой"
class PayPalPayment(Payment):
def pay(self, amount):
return f"Оплачено {amount}р через PayPal"
class PaymentFactory:
"""Фабрика для создания платежей"""
@staticmethod
def create(payment_type: str) -> Payment:
if payment_type == "card":
return CreditCardPayment()
elif payment_type == "paypal":
return PayPalPayment()
else:
raise ValueError(f"Unknown payment type: {payment_type}")
# Использование
factory = PaymentFactory()
payment = factory.create("card")
print(payment.pay(1000)) # Оплачено 1000р кредитной картой
payment = factory.create("paypal")
print(payment.pay(500)) # Оплачено 500р через PayPal
3. Builder (Строитель)
Поэтапное построение сложного объекта:
class QueryBuilder:
"""Builder для конструирования SQL запросов"""
def __init__(self):
self._select = "*"
self._from = None
self._where = None
self._limit = None
def select(self, columns: str):
self._select = columns
return self
def from_table(self, table: str):
self._from = table
return self
def where(self, condition: str):
self._where = condition
return self
def limit(self, count: int):
self._limit = count
return self
def build(self) -> str:
if not self._from:
raise ValueError("FROM clause is required")
query = f"SELECT {self._select} FROM {self._from}"
if self._where:
query += f" WHERE {self._where}"
if self._limit:
query += f" LIMIT {self._limit}"
return query
# Использование
query = (QueryBuilder()
.select("id, name, email")
.from_table("users")
.where("age > 18")
.limit(10)
.build())
print(query)
# SELECT id, name, email FROM users WHERE age > 18 LIMIT 10
4. Observer (Наблюдатель)
Подписка на события и уведомления:
from typing import List
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, message: str):
pass
class Subject:
"""Издатель событий"""
def __init__(self):
self._observers: List[Observer] = []
def attach(self, observer: Observer):
if observer not in self._observers:
self._observers.append(observer)
def detach(self, observer: Observer):
self._observers.remove(observer)
def notify(self, message: str):
for observer in self._observers:
observer.update(message)
class EmailSubscriber(Observer):
def update(self, message: str):
print(f"Email: получено сообщение: {message}")
class SMSSubscriber(Observer):
def update(self, message: str):
print(f"SMS: получено сообщение: {message}")
# Использование
subject = Subject()
email = EmailSubscriber()
sms = SMSSubscriber()
subject.attach(email)
subject.attach(sms)
subject.notify("Новое событие!") # Оба получат уведомление
5. Strategy (Стратегия)
Выбор алгоритма во время выполнения:
from abc import ABC, abstractmethod
class SortingStrategy(ABC):
@abstractmethod
def sort(self, data: list):
pass
class BubbleSort(SortingStrategy):
def sort(self, data: list):
n = len(data)
for i in range(n):
for j in range(0, n - i - 1):
if data[j] > data[j + 1]:
data[j], data[j + 1] = data[j + 1], data[j]
return data
class QuickSort(SortingStrategy):
def sort(self, data: list):
if len(data) <= 1:
return data
pivot = data[0]
less = [x for x in data[1:] if x <= pivot]
greater = [x for x in data[1:] if x > pivot]
return self.sort(less) + [pivot] + self.sort(greater)
class DataSorter:
def __init__(self, strategy: SortingStrategy):
self.strategy = strategy
def sort_data(self, data: list):
return self.strategy.sort(data)
# Использование
data = [5, 2, 8, 1, 9]
sorter = DataSorter(BubbleSort())
print(sorter.sort_data(data.copy())) # [1, 2, 5, 8, 9]
sorter = DataSorter(QuickSort())
print(sorter.sort_data(data.copy())) # [1, 2, 5, 8, 9]
6. Decorator (Декоратор)
Добавление функциональности к объектам:
from abc import ABC, abstractmethod
class Coffee(ABC):
@abstractmethod
def cost(self):
pass
@abstractmethod
def description(self):
pass
class SimpleCoffee(Coffee):
def cost(self):
return 5.0
def description(self):
return "Простой кофе"
class CoffeeDecorator(Coffee):
def __init__(self, coffee: Coffee):
self._coffee = coffee
class MilkDecorator(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 1.5
def description(self):
return self._coffee.description() + ", молоко"
class SugarDecorator(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 0.5
def description(self):
return self._coffee.description() + ", сахар"
# Использование
coffee = SimpleCoffee()
print(f"{coffee.description()}: {coffee.cost()}р")
# Простой кофе: 5.0р
coffee = MilkDecorator(coffee)
print(f"{coffee.description()}: {coffee.cost()}р")
# Простой кофе, молоко: 6.5р
coffee = SugarDecorator(coffee)
print(f"{coffee.description()}: {coffee.cost()}р")
# Простой кофе, молоко, сахар: 7.0р
7. Command (Команда)
Инкапсуляция запросов в объекты:
from abc import ABC, abstractmethod
from typing import List
class Command(ABC):
@abstractmethod
def execute(self):
pass
@abstractmethod
def undo(self):
pass
class LightOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.turn_on()
def undo(self):
self.light.turn_off()
class Light:
def turn_on(self):
print("Свет включен")
def turn_off(self):
print("Свет выключен")
class RemoteControl:
def __init__(self):
self._commands: List[Command] = []
self._history: List[Command] = []
def execute(self, command: Command):
command.execute()
self._history.append(command)
def undo(self):
if self._history:
command = self._history.pop()
command.undo()
# Использование
light = Light()
remote = RemoteControl()
command = LightOnCommand(light)
remote.execute(command) # Свет включен
remote.undo() # Свет выключен
8. Adapter (Адаптер)
Приведение несовместимых интерфейсов:
class OldPaymentGateway:
def process_charge(self, amount_cents):
return f"Обработано {amount_cents} центов"
class NewPaymentInterface:
def pay(self, amount_dollars):
pass
class PaymentAdapter(NewPaymentInterface):
def __init__(self, old_gateway: OldPaymentGateway):
self.old_gateway = old_gateway
def pay(self, amount_dollars):
amount_cents = int(amount_dollars * 100)
return self.old_gateway.process_charge(amount_cents)
# Использование
old_gateway = OldPaymentGateway()
adapter = PaymentAdapter(old_gateway)
result = adapter.pay(10.50) # 10.50 доллара
print(result) # Обработано 1050 центов
9. Facade (Фасад)
Упрощение сложной системы:
class Engine:
def start(self):
return "Двигатель запущен"
class Transmission:
def shift(self):
return "Включена 1-я передача"
class Lights:
def turn_on(self):
return "Фары включены"
class Car:
"""Фасад для сложной системы автомобиля"""
def __init__(self):
self.engine = Engine()
self.transmission = Transmission()
self.lights = Lights()
def start_car(self):
print(self.lights.turn_on())
print(self.engine.start())
print(self.transmission.shift())
return "Машина готова к движению"
# Использование
car = Car()
print(car.start_car())
# Фары включены
# Двигатель запущен
# Включена 1-я передача
# Машина готова к движению
10. Template Method (Шаблонный метод)
Определение скелета алгоритма в базовом классе:
from abc import ABC, abstractmethod
class DataProcessor(ABC):
"""Шаблонный метод для обработки данных"""
def process(self, data):
raw = self.read(data)
cleaned = self.clean(raw)
transformed = self.transform(cleaned)
return self.output(transformed)
@abstractmethod
def read(self, data):
pass
def clean(self, data):
return data # Default
@abstractmethod
def transform(self, data):
pass
def output(self, data):
return data # Default
class CSVProcessor(DataProcessor):
def read(self, data):
return data.split(",")
def clean(self, data):
return [x.strip() for x in data]
def transform(self, data):
return [x.upper() for x in data]
# Использование
processor = CSVProcessor()
result = processor.process("john, jane, mike")
print(result) # ["JOHN", "JANE", "MIKE"]
Когда какой паттерн использовать
- Singleton — конфиг, логгер, БД
- Factory — создание разных типов объектов
- Builder — построение сложных объектов
- Observer — события и подписки
- Strategy — выбор алгоритма
- Decorator — добавление функциональности
- Command — отмена операций, очереди
- Adapter — совместимость интерфейсов
- Facade — упрощение сложности
- Template Method — шаблоны для подклассов
Ключевой момент: не переусложняй. Используй паттерны когда они решают реальные проблемы, а не для их же ради.