Как реализуешь паттерн High Cohesion при Refactoring?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
High Cohesion при Refactoring
Cohesion (связность) — это мера, показывающая, насколько методы и переменные внутри класса связаны между собой функционально. High Cohesion означает, что все элементы класса работают вместе для достижения одной цели.
Проблема: Low Cohesion
Применение refactoring с целью увеличить cohesion начинается с識識верситета низкой связности:
// Плохо: Low Cohesion - класс делает слишком много
public class UserManager {
public void createUser(String name) { }
public void sendEmail(String to, String subject) { }
public void generateReport() { }
public void processPayment(double amount) { }
public void logActivity(String message) { }
}
Этот класс делает слишком много: управление пользователями, отправка email, отчёты, платежи, логирование. Это делает код сложным, тестируемым и подверженным изменениям.
Решение: Extract Class
Способ 1: Выделение отдельных классов для каждой ответственности:
// Управление пользователями
public class UserService {
public void createUser(String name) {
// Логика создания пользователя
}
}
// Отправка уведомлений
public class EmailService {
public void sendEmail(String to, String subject, String body) {
// Логика отправки email
}
}
// Обработка платежей
public class PaymentService {
public void processPayment(double amount) {
// Логика платежей
}
}
// Логирование
public class Logger {
public void log(String message) {
// Логирование
}
}
Увеличение Cohesion в существующем классе
Способ 2: Если класс всё ещё имеет смешанные ответственности, используй Method Extraction:
// До refactoring
public class OrderService {
public void processOrder(Order order) {
// Валидация
if (order.getItems().isEmpty()) throw new Exception("No items");
if (order.getAmount() <= 0) throw new Exception("Invalid amount");
// Сохранение
database.save(order);
// Отправка уведомления
emailService.send(order.getCustomer().getEmail(),
"Order created", buildEmailBody(order));
}
}
// После refactoring: High Cohesion
public class OrderService {
private final OrderValidator validator;
private final OrderRepository repository;
private final OrderNotificationService notifier;
public void processOrder(Order order) {
validator.validate(order);
repository.save(order);
notifier.notifyOrderCreated(order);
}
}
public class OrderValidator {
public void validate(Order order) {
if (order.getItems().isEmpty())
throw new ValidationException("No items");
if (order.getAmount() <= 0)
throw new ValidationException("Invalid amount");
}
}
public class OrderNotificationService {
private final EmailService emailService;
public void notifyOrderCreated(Order order) {
emailService.send(
order.getCustomer().getEmail(),
"Order created",
buildEmailBody(order)
);
}
private String buildEmailBody(Order order) {
// Логика построения текста письма
return "Order #" + order.getId() + " created";
}
}
Связь High Cohesion с Low Coupling
High Cohesion работает лучше всего в сочетании с Low Coupling (слабая зависимость между классами):
// Плохо: High Cohesion но High Coupling
public class UserService {
private EmailService emailService;
private PaymentService paymentService;
private ReportService reportService;
public UserService() {
// Жёсткие зависимости
this.emailService = new EmailService();
this.paymentService = new PaymentService();
this.reportService = new ReportService();
}
}
// Хорошо: High Cohesion и Low Coupling (через Dependency Injection)
public class UserService {
private final EmailService emailService;
private final PaymentService paymentService;
public UserService(EmailService emailService, PaymentService paymentService) {
this.emailService = emailService;
this.paymentService = paymentService;
}
}
Практические шаги для увеличения High Cohesion
- Найти неправильную ответственность — класс делает слишком много?
- Выделить методы — группировать связанные методы
- Создать новые классы — для каждой группы методов
- Использовать DI — внедрять зависимости через конструктор
- Тестировать — убедиться, что каждый класс имеет одну ответственность
Метрики для оценки Cohesion
- Все ли методы используют большинство полей класса?
- Можно ли разбить класс на несколько меньших?
- Есть ли методы, которые не связаны с остальными?