Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Low Coupling — принцип слабой связанности
Low coupling (слабая связанность) — один из фундаментальных принципов хорошего software design. Он означает, что модули и компоненты системы должны быть максимально независимы друг от друга.
Что такое coupling (связанность)?
High coupling — компоненты сильно зависят друг от друга:
# Плохо: UserService зависит от конкретной реализации DatabaseConnector
class DatabaseConnector:
def get_user(self, user_id):
# Реальное подключение к БД
pass
class UserService:
def __init__(self):
# Жёсткая зависимость на конкретный класс
self.db = DatabaseConnector()
def get_user(self, user_id):
return self.db.get_user(user_id)
Low coupling — компоненты минимально зависят через интерфейсы:
# Хорошо: UserService зависит от абстракции
from abc import ABC, abstractmethod
class UserRepository(ABC):
@abstractmethod
def get_user(self, user_id: int) -> dict:
pass
class UserService:
def __init__(self, repository: UserRepository):
self.repository = repository
def get_user(self, user_id: int) -> dict:
return self.repository.get_user(user_id)
Проблемы High Coupling
1. Сложность тестирования
Невозможно протестировать без реальных зависимостей — медленно и непредсказуемо.
2. Сложность изменений
Изменение в одном месте ломает много других частей кода.
3. Трудность переиспользования
Классы привязаны к конкретным реализациям и не могут быть переиспользованы в других контекстах.
Как достичь Low Coupling
1. Инъекция зависимостей
class OrderService:
def __init__(self, payment_gateway, email_service, logger):
self.payment = payment_gateway
self.email = email_service
self.logger = logger
def place_order(self, order_data):
self.logger.info('Processing order')
result = self.payment.process(order_data)
self.email.send_confirmation(order_data['email'])
return result
2. Работа через интерфейсы
from typing import Protocol
class Logger(Protocol):
def log(self, message: str) -> None: ...
def error(self, message: str) -> None: ...
class FileLogger:
def log(self, message: str) -> None:
with open('log.txt', 'a') as f:
f.write(message)
def error(self, message: str) -> None:
with open('errors.txt', 'a') as f:
f.write(message)
3. Event-driven архитектура
from dataclasses import dataclass
@dataclass
class UserRegisteredEvent:
user_id: int
email: str
class EventBus:
def __init__(self):
self.handlers = {}
def subscribe(self, event_type, handler):
if event_type not in self.handlers:
self.handlers[event_type] = []
self.handlers[event_type].append(handler)
def publish(self, event):
event_type = type(event)
for handler in self.handlers.get(event_type, []):
handler(event)
class UserService:
def __init__(self, event_bus: EventBus):
self.event_bus = event_bus
def register(self, email: str):
user_id = self.create_user(email)
self.event_bus.publish(UserRegisteredEvent(user_id, email))
return user_id
class EmailService:
def __init__(self, event_bus: EventBus):
event_bus.subscribe(UserRegisteredEvent, self.on_user_registered)
def on_user_registered(self, event: UserRegisteredEvent):
self.send_welcome_email(event.email)
Преимущества Low Coupling
✅ Легче тестировать с mock dependencies ✅ Легче менять — изменения локализованы ✅ Легче переиспользовать — компоненты независимы ✅ Легче масштабировать ✅ Понятнее архитектура — зависимости явны
Итоги
Low coupling — это про независимость компонентов. Когда ваша система состоит из слабо связанных модулей, разработка становится быстрее, код надёжнее, а изменения безопаснее.