← Назад к вопросам
Что такое High Cohesion, применимо к микросервисной архитектуре?
2.4 Senior🔥 141 комментариев
#DevOps и инфраструктура#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
High Cohesion в микросервисной архитектуре: принцип, практика, примеры
Что такое High Cohesion
High Cohesion (высокая связанность) — это принцип дизайна, который говорит: компоненты внутри одного модуля должны быть тесно связаны друг с другом и служить одной цели.
Определение простыми словами:
- Cohesion (связанность) — мера того, насколько компоненты внутри модуля связаны
- High Cohesion — все части модуля работают вместе для достижения одной цели
- Low Cohesion — части модуля делают разные вещи, не связанные между собой
Пример Low Cohesion (плохо)
// ❌ Класс с низкой связанностью
class UserService {
// Работает с пользователями
createUser(userData) { }
getUser(id) { }
updateUser(id, data) { }
// Работает с платежами (не относится к пользователям!)
processPayment(amount) { }
refundPayment(transactionId) { }
// Отправляет отчёты (тоже не связано с пользователями)
generateMonthlyReport() { }
sendReportByEmail() { }
}
// Проблемы:
// - UserService делает слишком много
// - Изменение платёжной логики влияет на User сервис
// - Сложно переиспользовать компоненты
// - Тестирование сложное (нужно мокировать платежи для теста юзера)
Пример High Cohesion (хорошо)
// ✅ Высокая связанность
// UserService фокусируется ТОЛЬКО на пользователях
class UserService {
createUser(userData) { }
getUser(id) { }
updateUser(id, data) { }
deleteUser(id) { }
findByEmail(email) { }
}
// PaymentService фокусируется ТОЛЬКО на платежах
class PaymentService {
processPayment(amount, userId) { }
refundPayment(transactionId) { }
getTransactionHistory(userId) { }
}
// ReportService фокусируется ТОЛЬКО на отчётах
class ReportService {
generateMonthlyReport() { }
sendReportByEmail(email) { }
}
// Пример использования
class OrderController {
constructor(
private userService: UserService,
private paymentService: PaymentService,
private reportService: ReportService
) {}
async createOrder(userId: string, amount: number) {
const user = await this.userService.getUser(userId);
const payment = await this.paymentService.processPayment(amount, userId);
await this.reportService.generateMonthlyReport();
}
}
High Cohesion в микросервисной архитектуре
В микросервисах High Cohesion означает, что каждый микросервис должен иметь чётко определённую область ответственности (Bounded Context из DDD).
Пример архитектуры:
Микросервисная система:
┌─────────────────┐
│ User Service │ Отвечает за: управление пользователями, аутентификацию, профили
└────────┬────────┘
│
├─> UserRepository
├─> AuthenticationService
└─> ProfileService
┌─────────────────┐
│ Payment Service │ Отвечает за: обработка платежей, транзакции, рефанды
└────────┬────────┘
│
├─> PaymentRepository
├─> StripeIntegration
└─> RefundService
┌─────────────────┐
│ Order Service │ Отвечает за: управление заказами, статусы заказов
└────────┬────────┘
│
├─> OrderRepository
├─> OrderStatusService
└─> InventoryIntegration
┌─────────────────┐
│ Notification │ Отвечает за: отправка уведомлений, логирование
│ Service │
└────────┬────────┘
│
├─> EmailService
├─> SMSService
└─> LoggingService
Что НЕ ДЕЛАТЬ: Low Cohesion микросервисы
// ❌ ПЛОХО: Микросервис делает слишком много
class OrderService {
// Логика заказов
createOrder() { }
getOrder() { }
updateOrder() { }
cancelOrder() { }
// Логика платежей (не её ответственность!)
processPayment() { }
refundPayment() { }
// Логика доставки (не её ответственность!)
scheduleDelivery() { }
trackDelivery() { }
// Логика уведомлений (не её ответственность!)
sendOrderConfirmation() { }
sendDeliveryNotification() { }
}
// Проблемы:
// - Микросервис слишком большой
// - Сложно масштабировать (нужно масштабировать всё, даже если проблема только в платежах)
// - Сложнее разбираться в коде
// - Изменение логики платежей требует рефакторинга Order Service
Что ДЕЛАТЬ: High Cohesion микросервисы
// ✅ ХОРОШО: Каждый микросервис имеет чёткую ответственность
// Order Service - ТОЛЬКО логика заказов
@Controller('orders')
export class OrderController {
constructor(private orderService: OrderService) {}
@Post()
async createOrder(@Body() data: CreateOrderDTO) {
return await this.orderService.create(data);
}
@Get(':id')
async getOrder(@Param('id') id: string) {
return await this.orderService.getById(id);
}
}
export class OrderService {
async create(data: CreateOrderDTO) {
// Создаём заказ
const order = await this.orderRepository.create(data);
// Публикуем событие - пусть другие сервисы на него подпишутся
await this.eventBus.publish('order.created', { orderId: order.id });
return order;
}
async cancel(orderId: string) {
const order = await this.orderRepository.getById(orderId);
order.status = 'cancelled';
await this.orderRepository.save(order);
// Публикуем событие для других сервисов
await this.eventBus.publish('order.cancelled', { orderId });
}
}
// Payment Service - ТОЛЬКО логика платежей
@Controller('payments')
export class PaymentController {
constructor(private paymentService: PaymentService) {}
@Post()
async processPayment(@Body() data: ProcessPaymentDTO) {
return await this.paymentService.process(data);
}
}
export class PaymentService {
async process(data: ProcessPaymentDTO) {
const payment = await this.stripeService.charge(data.amount);
await this.paymentRepository.save(payment);
// Публикуем событие - Order Service узнает, что платёж прошёл
await this.eventBus.publish('payment.completed', {
paymentId: payment.id,
orderId: data.orderId
});
return payment;
}
}
// Notification Service - ТОЛЬКО логика уведомлений
@Injectable()
export class NotificationSubscriber {
constructor(private emailService: EmailService) {}
@OnEvent('order.created')
async onOrderCreated(event: OrderCreatedEvent) {
await this.emailService.send(event.userId, 'Order Confirmation');
}
@OnEvent('payment.completed')
async onPaymentCompleted(event: PaymentCompletedEvent) {
await this.emailService.send(event.userId, 'Payment Confirmed');
}
}
Как достичь High Cohesion: практические шаги
1. Используй DDD (Domain-Driven Design)
// Identify Bounded Contexts
const boundedContexts = [
'User Management', // User Service
'Order Management', // Order Service
'Payment Processing', // Payment Service
'Inventory Management', // Inventory Service
'Shipping & Delivery' // Shipping Service
];
// Каждый микросервис соответствует одному Bounded Context
**2. Используй Event-Driven Communication
// Вместо синхронных вызовов между сервисами
// UserService -> PaymentService -> OrderService (ПЛОХО: tight coupling)
// Используй асинхронные события
UserService ----publishes----> order.created ----subscribes----> OrderService
|
v
PaymentService
**3. Определи API граници каждого сервиса
// Order Service API
POST /orders - Create order
GET /orders/:id - Get order
PUT /orders/:id - Update order
DELETE /orders/:id - Cancel order
// Это всё, что Order Service должен делать
// Платежи, доставку, уведомления - делают другие сервисы
**4. Используй Repository Pattern
// Каждый сервис имеет свой repository для своей БД
UserService
├── UserRepository (работает с users table)
└── БД: user_service_db
OrderService
├── OrderRepository (работает с orders table)
└── БД: order_service_db
PaymentService
├── PaymentRepository (работает с payments table)
└── БД: payment_service_db
// Это гарантирует, что сервисы не делят БД
Когда High Cohesion нарушается
Антипаттерны, которых нужно избегать:
- God Service — один сервис делает всё
- Chatty Services — слишком много синхронных вызовов
- Shared Database — несколько сервисов работают с одной БД
- Circular Dependencies — Service A зависит от B, а B от A
- Anemic Models — сервисы содержат только данные, без логики
High Cohesion vs Loose Coupling
// High Cohesion: компоненты внутри сервиса тесно связаны
// Loose Coupling: сервисы слабо связаны друг с другом
// Правильный баланс:
Intra-service: High Cohesion (UserService содержит все части логики для users)
Inter-service: Loose Coupling (сервисы общаются через events/API)
Практический пример из реального проекта
// Payment Platform (где я работал)
// ✅ High Cohesion: Auth Service
auth-service/
├── controllers/
│ └── AuthController
├── services/
│ ├── JwtService
│ ├── PasswordService
│ └── SessionService
├── repositories/
│ └── UserRepository
└── entities/
└── User
// Только логика аутентификации и авторизации
// Не делает платежи, заказы, уведомления
// ✅ High Cohesion: Payment Service
payment-service/
├── controllers/
│ └── PaymentController
├── services/
│ ├── StripeService
│ ├── RefundService
│ └── TransactionService
├── repositories/
│ └── PaymentRepository
└── entities/
└── Payment
// Только логика платежей
// Не делает управление пользователями, доставку
Выводы
- High Cohesion — это принцип дизайна, который делает код более понятным и поддерживаемым
- В микросервисах это означает: каждый сервис отвечает за одну область
- DDD Bounded Contexts помогают идентифицировать границы сервисов
- Event-Driven архитектура позволяет сервисам взаимодействовать без tight coupling
- Результат: система легче масштабировать, тестировать и понимать
High Cohesion + Loose Coupling = хорошо спроектированная микросервисная система.