Как стать автором
Обновить

Тысячная статья про принципы SOLID

Время на прочтение3 мин
Количество просмотров27K

Ещё будучи совсем-совсем начинающим разработчиком, я услышал про принципы 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, конечно).

Понятное дело, что мое понимание принципов не является единственно верным (а то и вообще неправильным). Однако, такое объяснение принципов мне видится очень понятным и прикладным.

Теги:
Хабы:
+13
Комментарии36

Публикации

Истории

Работа

Ближайшие события