Ответ
Cohesion (Связность) — это мера того, насколько тесно связаны и сфокусированы на одной задаче обязанности внутри одного модуля (класса, компонента). Coupling (Связанность) — это мера того, насколько сильно один модуль зависит от других модулей.
Цель: Стремиться к высокой связности (High Cohesion) и низкой связанности (Low Coupling). Это фундаментальный принцип проектирования, ведущий к поддерживаемому, тестируемому и гибкому коду.
Высокая связность (High Cohesion)
Класс с высокой связностью делает одну четко определенную вещь. Все его методы и свойства тесно связаны с его основной ответственностью.
Пример класса с высокой связностью:
// Этот класс отвечает только за логирование. Все его методы связаны с этой одной задачей.
public class FileLogger
{
private readonly string _logFilePath;
public FileLogger(string logFilePath) => _logFilePath = logFilePath;
public void LogInfo(string message) => WriteToFile($"[INFO] {DateTime.Now}: {message}");
public void LogError(string message, Exception ex) => WriteToFile($"[ERROR] {DateTime.Now}: {message} - {ex.Message}");
private void WriteToFile(string text) => File.AppendAllText(_logFilePath, text + Environment.NewLine);
}
Низкая связанность (Low Coupling)
Модули с низкой связанностью минимально зависят от внутреннего устройства друг друга. Зависимости управляются через абстракции (интерфейсы).
Пример низкой связанности (внедрение зависимости):
// OrderService зависит от абстракции ILogger, а не от конкретной реализации.
// Это снижает связанность и упрощает тестирование.
public class OrderService
{
private readonly ILogger _logger;
private readonly IOrderRepository _repository;
// Зависимости внедряются извне
public OrderService(ILogger logger, IOrderRepository repository)
{
_logger = logger;
_repository = repository;
}
public void ProcessOrder(Order order)
{
_logger.LogInfo("Processing order " + order.Id);
// Логика обработки...
_repository.Save(order);
}
}
Пример высокой связанности (плохая практика):
public class OrderService
{
// Прямое создание зависимостей внутри класса делает его тесно связанным с конкретными реализациями.
private FileLogger _logger = new FileLogger("log.txt");
private SqlOrderRepository _repository = new SqlOrderRepository();
// ...
}
Итог: Высокая связность и низкая связанность делают код более модульным, что упрощает его понимание, изменение, повторное использование и модульное тестирование.