Comments 33
А вот насчёт внесения ReportShapesSize в классы — это не нарушение SRP?
Вот я, как математик, сижу описываю прекрасные классы кубов, шаров, призм. А потом какой-нибудь продажник из соседнего отдела понавтыкает мне в код свои *$%е методы для одному ему нужного отчёта (да ещё и зависимости притащит от какого-нибудь, пусть не конкретного жирного CrystalReports, но даже абстрактного IReport). Мне было бы неприятно.
Но таким образом любые абстракции, предоставляемые сторонними библиотеками и фреймворками, обрастают обёртками.
Хм.
Фреймворки и так представляют абстракции.
Если так хочется городить огород над его абстракциями, то зачем вообще фреймворк?
Вот был у меня код с log4net:
var logger = log4net.LogManager.GetLogger(typeof(ProductManager));
logger.Info("The product is purchased.");
(собственно, чем это отличается от FileLogger в примере?)
Нет, обязательно надо избавить свой код от зависимости от log4net, написать обёртку и интерфейс ILogger, чтобы было по феншую.
Если нужно сделать код юнит тестируемым (подставить моки) относительно уровня и контента логируемых сообщений, то да. Иначе, как хотите. Тут нет единой рекомендации. Прямое использование лог фор нет является имхо жестковатым, если хотите проверять в юнит тестах то, что Вы логируете.
Так и правда стоит делать в общих библиотеках — ведь их пользователь может использовать любой способ ведение логов. А вот в своих программах, я считаю, делать абстракции над абстракциями не стоит.
Тут непонятно, где подвести «общий знаменатель». У кажого логера свои фичи, а каждая библиотека может выставить свои требования к логгеру. Конверторам придётся либо что-то игнорить, либо реализовывать недостающее.
С другой стороны наличие метода или свойства, возвращающего площадь, будет оправданно для геометрической фигуры. Хелпер бы уже можно было завязать на него.
Современные логгеры имеют достаточную гибкость и настолько разнообразный набор аппендеров, что всегда удовлетворяли любым техническим требованиям во всех моих проектах до сих пор.
Никогда у меня не было технически оправданной ситуации для абстракции для логгера.
То же касается и инжектора зависимостей.
И напротив, в проектах где были введены эти абстракции, они усложняли код и мешали.
У меня был случай когда из-за проблем с лицензией приходилось менять Unity IoC контейнер на кастомный. В случаем с логгерами, в принципе log4net с его аппендерами бывает достаточным. Но мало ли что? Вдруг придется… Кроме того, абстракция логгера поможет при юнит тестировании, если есть требования на логирование. Например, в таком-то случае нужно логировать то-то с таким-то уровнем. В моем проекте такое встречается довольно часто.
Например, было желание переехать с NLog на Serilog. И, кстати, переехали в итоге.
Правда в абстракции для логгера я тоже не вижу смысла, как для IoC контейнера.
Переехать с одного логгера на другой оказалось несложно без всяких абстракций.
Кто-нибудь когда-нибудь имел необходимость менять логгер в существующем проекте?
Да регулярно. Заменить самописный логгер на что-то более функциональное.
В первом примере в разделе "Хрупкость" похоже опечатка: "roleId == 1 && roleId == 2", или это так задумано? Условие всегда ложно, там скорее всего "или" должно быть..
В этом случае класс A перестает зависеть от конкретного класса B, а зависит лишь от интерфейса IComponent.
А если интерфейс нужно поменять? Еще больше правок придется сделать.
Все может поменяться. Обычно интерфейсы меняются реже чем их реализации. Закрыть все от изменений не получится.
В чем тогда проблема поменять реализацию класса B?
Признаки проблемного дизайна