Как используются принципы SOLID, в частности буквы O и I?
Что проверяют
Можете ли вы показать эти принципы на реальном коде C#, а не пересказать определения. Обычно следом просят пример из своего проекта или спрашивают, где OCP превращается в оверинжиниринг.
Как отвечать
Open/Closed: модуль открыт для расширения и закрыт для изменения. На практике новый вариант поведения добавляется новым классом, а не новой веткой в switch.
- стратегии через DI:
IDiscountPolicyс несколькими реализациями вIServiceCollection. Сервис принимаетIEnumerable<IDiscountPolicy>и не меняется, когда появляется новая скидка; - конвейеры: middleware в ASP.NET Core и
IPipelineBehaviorв MediatR добавляют логирование, валидацию и ретраи, не трогая обработчики; - декораторы: кеширующая обёртка над
IRepositoryповерх готовой реализации; - методы расширения: добавляют поведение типу, исходники которого вы не меняете.
Interface Segregation: клиент не должен зависеть от методов, которые ему не нужны. Хороший пример есть прямо в BCL: IReadOnlyList<T> и IReadOnlyCollection<T> рядом с IList<T>, чтобы метод, который только читает, не требовал возможности Add. В своём коде это разделение IOrderReader и IOrderWriter: сервис отчётов получает только чтение, а мок в тесте реализует два метода вместо пятнадцати.
Покажите, как принципы связаны: узкие интерфейсы делают расширение дешевле, потому что новая реализация выполняет маленький контракт. И приведите свой пример с цифрами: сколько вариантов добавили без правки старого кода. Если такого случая не было, честно скажите это и разберите, где в вашем проекте был бы уместен OCP.
Где спотыкаются
Приводят учебный пример с Shape.Area() и не могут назвать ни одного случая из работы. Интервьюер почти всегда уточняет: «а у вас где?».
Применяют OCP заранее: заводят стратегию и фабрику под единственный вариант, который никогда не расширится. Абстракцию оправдывает второй или третий реальный случай.
Путают ISP с правилом «один метод в интерфейсе». Цель в том, чтобы интерфейс совпадал с нуждами клиента, а не в дроблении до атомов. Верный признак нарушения: реализации бросают NotImplementedException.