Читал, что SOLID - это хорошие рекомендации, проверенные временем, но пихать их в каждый проект не стоит. Гуглил примеры, когда его применять не нужно и не нашел. Скажите, в каких случаях применение SOLID неоправданно?
Ответ
Касательно любого паттерна/принципа разработки можно сказать:
Если вы следуете ему, нет гарантии, что ваш код автоматически станет более корректным, расширяемым и сопровождаемым.
Если вы не следуете ему, нет гарантии, что ваш код автоматически становится проблемным, не расширяемым и не сопровождаемым.
Следуя ему вы можете решить одну из проблем своего кода (или не решить), но создать новые проблемы.
Также имеет место быть неполное или даже некорректное понимание используемых принципов/паттернов. И возможно даже возведение в абсолют, когда буквальное следование им становится превыше здравого смысла.
Таким образом вопрос не в том, когда не нужно использовать SOLID, а в том, насколько использовать каждый из его принципов в своем, конкретном случае.
S - Single Responsibility Principle
Класс должен иметь только одну ответственность
При недостаточном разделении ответственности получаем антипаттерн "god", класс становиться кухонным комбайном. В то же время при чрезмерном разделении код может раздробится так, что в каждом классе остается чуть ли не один метод, состоящий из одной строки кода. В итоге сложность восприятия может увеличиться.
O - Open/Closed Principle
Программные сущности должны быть открытыми для расширения, но закрытыми для модификации
Возьмем ситуацию, когда базовый класс содержит общие детали реализации, а несколько наследников уточняют её. Следуя этому принципу, при добавлении новых потомков, их общие черты придется выносить в один промежуточный класс, чтобы не трогать базовый. Со временем может образоваться причудливая иерархия, хотя, вероятно, стоило рассмотреть вариант модификации базового класса (несмотря на возможные поломки уже имеющихся потомков).
L - Liskov Substitution Principle
Объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы
Ради обеспечения этого принципа иногда приходится использовать сомнительные решения. К примеру класс Ellipse имеет подкласс Circle, который является случаем Ellipse с одинаковой длиной по осям X и Y. В соответствии с принципом, подкласс Circle обязан реализовать поведение родителя. Если Ellipse содержит метод stretchX, позволяющий модифицировать длину по оси X, то класс Cirlce также обязан реализовать это поведение, несмотря на то, что для круга это невозможно.
I - Interface Segregation Principle
Много интерфейсов, специально предназначенных для клиентов, лучше, чем один интерфейс общего назначения
Требует, чтобы клиенты не зависели от интерфейсов, которые они не используют. На практике, особенно при плохо продуманной архитектуре, это может вылиться в дробление на очень мелкие интерфейсы из одного-двух методов, чтобы удовлетворить множество клиентов.
D - Dependency Inversion Principle
Принцип инверсии зависимости
Возьмем ситуацию когда объект класса A вызывает методы объекта класса B. Значит A зависит от B. С применением этого принципа, объект типа B должен быть инстанциирован вне A и передан как зависимость в A. Без применения этого принципа, это может сделать сам объект A, что во многих случаях гораздо удобнее.
Основано на http://www.tonymarston.net/php-mysql/not-so-solid-oo-principles.html. В процессе чтения узнал много нового. Холивар приветствуется )
Комментариев нет:
Отправить комментарий