← Назад к вопросам

Как реализуешь паттерн High Cohesion при Refactoring?

2.0 Middle🔥 151 комментариев
#SOLID и паттерны проектирования

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

  1. Найти неправильную ответственность — класс делает слишком много?
  2. Выделить методы — группировать связанные методы
  3. Создать новые классы — для каждой группы методов
  4. Использовать DI — внедрять зависимости через конструктор
  5. Тестировать — убедиться, что каждый класс имеет одну ответственность

Метрики для оценки Cohesion

  • Все ли методы используют большинство полей класса?
  • Можно ли разбить класс на несколько меньших?
  • Есть ли методы, которые не связаны с остальными?
Как реализуешь паттерн High Cohesion при Refactoring? | PrepBro