Комментарии 6
Спасибо за статью! На примерах очень удобно)
Я тоже использую SOLID в iOS-разработке!
// Liskov's substitution principle is for the weak.
@available(*, unavailable)
override init() {
fatalError("Never to be called")
}
Важно находить золотую середину между hardcode и softcode и принимать взвешенные и оправданные решения.
Как бы вы реализовывали код из примера с PhysicalProduct/DigitalProduct, если бы видов продуктов было гораздо больше, а также один вид мог переходить/превращаться в другой вид?
Здравствуйте, довольно сложно полностью картину представить - можете дать чуть больше контекста/примеров?
в моем случае это была view model, соответствующая секциям и ячейкам таблицы. Видов ячеек было штук 10, набор данных в UI для них значительно отличался, пользователь мог взаимодействовать с ячейками, добавляя, перемещая, удаляя с задержкой и возможностью отмены действия. При взаимодействии с ячейкой ее тип мог меняться на другой с совершенно другими контролами.
Тогда наиболее простым вариантом выглядело зашить все возможные данные в один объект - и пусть каждая ячейка выбирает из него только ту инфу, которая ей нужна. Меняется тип ячейки - другая ячейка выберет из того же объекта другие данные. Т.е. по solid получалось максимум приводить объект с raw набором данных к определенному протоколу, так как следовать принципам solid и приводить каждый тип данных к каждому другому типу было нецелесообразно.
Довольно сложно все же представить без кода, но предположу, что в вашем случае должен быть какой-то общий для всех ViewModel интерфейс. Помимо него нужны интерфейсы, отвечающие за разную функциональность или набор данных - то есть, по сути все как в примере из статьи, если я правильно понимаю, только интерфейсов будет больше.
Забавное следствие из OCP, о котором Вы не упомянули.
Если сохраняется стабильность протокола, то не повышается мажорная версия (расширение протокола повышает лишь минорную версию, определение Symver). Отсутствие изменения мажорной версии позволяет в многомодульных системах не менять зависимые модули. Таким образом мы добиваемся исполнения принципа инверсии зависимости за счет исполнения принципа OCP. Стоит нарушить принцип OCP в многомодульных системах (да и не только, просто в многомодульных это нагляднее, чем в связном монолите, но и в последнем эффект тот же) и вы теряете DIP и приобретаете зависимость верхних модулей от нижних. Что в свою очередь ведет к тому, что при изменении нижнего модуля вы вынуждены переписать полприложения.
Таким образом, следование OCP упрощает следование DIP. В статье вы указали на обратное утверждение: "Следование DIP упрощает следование LSP и OCP". Оно тоже верное. А отсюда следует, что начиная правильно использовать любой из этих принципов, вы, желая того или нет, вынуждены будете следовать всем трем. И на самом деле всем 5, ибо они все аналогично упрощают работу друг с другом. В итоге Вы получите синергию всех 5 методов, значительно ускоряющих вашу работу. Эти 5 методов взаимно не позволят вам нарушить ни один из них.
Такие забавные пирожки у тёти Клавы :)
За статью – респект. Примеры хорошие.
Принципы SOLID на примере iOS-разработки