Ещё будучи совсем-совсем начинающим разработчиком, я услышал про принципы SOLID и, конечно же, совершенно их не понял. Их не помогли понять ни лекции Дядюшки Боба, ни книга его же авторства, не несколько десятков (а то и сотен) статей в интернете, которые я тогда прочитал (по какой-то причине мне эти принципы казались чем-то очень важным, прямо-таки фундаментальным). Сейчас я могу сказать, что понимаю их как-то, по-своему, и пользуюсь ими каждый день. В данной короткой статье хочу поделиться своими размышлениями о сути принципов, которые были бы понятны тому мне из прошлого, который пытался загуглить доступное объяснение этих принципов.
Главный принцип разработки
Всю суть SOLID можно выразить простым допущением: «Как правило разработчикам приходится реализовывать новую функциональность, а не менять старую. Так давайте писать код так, чтобы новое было легко писать, а старое — тяжело сломать«. Этот основной принцип совпадает с буквой О — open–closed principle, принципом открытости-закрытости. Все остальные принципы направлены именно на то, чтобы обеспечить именно такую структуру кода, при которой некоторый рефакторинг ничего не ломает, и в то же время новые фичи без проблем реализуются.
Буква S
Принцип единственной ответственности (он же single-responsibility principle) говорит о том, что какие-угодно блоки приложения (методы, классы, модули) лучше создавать такого размера, чтобы их не приходилось потом часто менять («иметь одну и только одну причину для изменений»). То есть код написан один раз, и мы в принципе-то не хотим его менять. Но на всякий случай лучше сделать так, чтобы вероятность необходимости изменений была как можно более низкой.
Буква L
Принцип подстановки Барбары Лисков (Liskov Substitution Principle) говорит, что если мы дописываем новых наследников к классу, то нужно это делать таким образом, чтобы не пришлось менять весь старый код, который этих самых наследников будет использовать (старый код-то и не знает ничего про наследников). Опять-таки: легко дописываем, но тяжело ломаем.
Буква I
Принцип разделения интерфейса (interface segregation principle) — производный принцип от первой буквы, S. Дело в том, что сформулировать «единую ответственность» в терминах интерфейса бывает сложно, а этот принцип нам однозначно говорит: если какая-то реализация не использует некоторые методы интерфейса, то эти методы в интерфейсе лишние. Здесь проще всего показать на примере: в Java вот есть интерфейс Collection с методами в духе add(), remove() и так далее. И в неизменяемых реализациях коллекций эти методы, ясное дело, не нужны. Поэтому, согласно принципу I, интерфейс стоит разделить на Collection и его наследника, MutableCollection (как сделано в Kotlin, например). Цель у этого всего опять-таки одна: чем меньше методов в интерфейсе, тем реже его придется менять (и тем меньше шанс что-нибудь сломать). Ну и дописывать новые интерфейсы проще, чем дописывать методы в существующие интерфейсы.
Буква D
Принцип инверсии зависимостей (dependency inversion principle) — принцип-компаньон буквы L. Чтобы можно было легко дописывать наследников или менять реализации, нужно, чтобы код, который все это использует, не приходилось менять. То есть хочется, чтобы он зависел от чего-то постоянного, в определении принципа называемого «абстракцией». Принцип такой же, как и у остальных: мы ввели абстракцию, написали какой-то код опираясь на эту самую абстракцию. Затем можно писать разные реализации абстракции, менять реализацию уже написанных — на тот код, который опирается на неё, это не повлияет (при выполнении правила L, конечно).
Понятное дело, что мое понимание принципов не является единственно верным (а то и вообще неправильным). Однако, такое объяснение принципов мне видится очень понятным и прикладным.
ссылка на оригинал статьи https://habr.com/ru/post/599943/
Добавить комментарий