TODO: отвалидировать – текст собран автоматически из материалов курса на Google Drive, проверьте формулировки и код.
Степень связности – мера неотрывности элемента от других элементов. Слабое зацепление – это оценочная модель, которая подсказывает, как распределить обязанности.
Каким бывает класс со слабым зацеплением
- имеет слабую зависимость от других классов;
- не зависит от внешних изменений: правка в одном классе слабо влияет на остальные;
- прост для повторного использования.
Чем плохо сильное зацепление
- затрудняется понимание логики модулей;
- усложняется модификация программы;
- появляются проблемы с тестированием;
- отдельный модуль невозможно переиспользовать.
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
public class ReportService
{
private readonly PostgresConnection _db = new PostgresConnection();
}
// Слабое зацепление: зависимость от абстракции, а не от реализации
public class ReportService
{
private readonly IReportStorage _storage;
public ReportService(IReportStorage storage) => _storage = storage;
}
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
class ReportService {
private:
PostgresConnection db_;
};
// Слабое зацепление: зависимость от абстракции, а не от реализации
class ReportService {
public:
explicit ReportService(IReportStorage& storage) : storage_(storage) {}
private:
IReportStorage& storage_;
};
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
type ReportService struct {
db *PostgresConnection
}
// Слабое зацепление: зависимость от интерфейса, а не от реализации
type ReportStorage interface {
Save(report Report) error
}
type ReportService struct {
storage ReportStorage
}
func NewReportService(storage ReportStorage) *ReportService {
return &ReportService{storage: storage}
}
# Сильное зацепление: сервис намертво привязан к конкретной СУБД
class ReportService:
def __init__(self) -> None:
self._db = PostgresConnection()
# Слабое зацепление: зависимость от абстракции, а не от реализации
class ReportService:
def __init__(self, storage: ReportStorage) -> None:
self._storage = storage
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
class ReportService {
private readonly db = new PostgresConnection();
}
// Слабое зацепление: зависимость от абстракции, а не от реализации
class ReportService {
constructor(private readonly storage: ReportStorage) {}
}
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
public class ReportService {
private final PostgresConnection db = new PostgresConnection();
}
// Слабое зацепление: зависимость от абстракции, а не от реализации
public class ReportService {
private final ReportStorage storage;
public ReportService(ReportStorage storage) {
this.storage = storage;
}
}
// Сильное зацепление: сервис намертво привязан к конкретной СУБД
class ReportService {
private val db = PostgresConnection()
}
// Слабое зацепление: зависимость от абстракции, а не от реализации
class ReportService(private val storage: ReportStorage)
Второй вариант можно протестировать, подставив хранилище в памяти, и перевести на другую СУБД, не трогая сам сервис.