Что такое принципы SOLID и примеры нарушения принципов C и D
Что проверяют
Знаете ли вы все пять и умеете ли привести конкретные примеры нарушений с решением.
Как отвечать
Кратко по всем пяти: единственная ответственность, открытость для расширения при закрытости для изменения, подстановка наследника без нарушения корректности, разделение интерфейсов, инверсия зависимостей.
Дальше подробно по двум последним, ради которых и задан вопрос.
Разделение интерфейсов. Нарушение выглядит как толстый интерфейс, который реализациям приходится поддерживать целиком:
interface IRepository<T> {
T GetById(int id);
IEnumerable<T> GetAll();
void Add(T item);
void Update(T item);
void Delete(int id);
void BulkImport(Stream data);
}Хранилище, доступное только для чтения, вынуждено реализовать изменяющие методы и бросать в них исключение о неподдерживаемой операции. Это заодно нарушает и принцип подстановки. Плюс потребитель, которому нужно одно чтение, зависит от всего интерфейса, и его тесты обрастают заглушками для методов, которые он не вызывает.
Решение: разделить на узкие интерфейсы чтения и записи, а реализация может поддерживать оба.
Инверсия зависимостей. Нарушение это создание конкретной зависимости внутри класса:
class OrderService {
private readonly SqlConnection _db = new("Server=..."); // жёсткая привязка
}Класс намертво связан и с конкретной базой, и со строкой подключения. Подменить хранилище нельзя, протестировать без настоящей базы нельзя, а строка подключения оказалась зашита в код.
Решение: зависеть от абстракции и получать её через конструктор. Причём интерфейс объявляется на стороне потребителя, а не рядом с реализацией: тогда направление зависимости действительно разворачивается, и предметный слой перестаёт знать о слое данных.
Признак нарушения, который легко заметить: класс невозможно создать в тесте без поднятия инфраструктуры.
Где спотыкаются
Реализуют толстый интерфейс с исключениями о неподдерживаемых операциях.
Создают зависимости оператором создания внутри класса.
Объявляют интерфейс рядом с реализацией и считают, что применили инверсию.
Заводят интерфейс на каждый класс, называя это принципом.