Справочная: разбираемся с принципами SOLID

    Расскажем, кто их придумал и в чем они заключаются. Также поговорим о критике этого подхода — о том, почему некоторые разработчики отказываются следовать SOLID-методологиям.


    Фото — nesa — Unsplash

    Акроним


    SOLID — обозначает пять первых принципов объектно-ориентированного программирования:

    • Единственной ответственности (SRP). Один модуль/класс — одна задача. Кажется, что-то такое мы уже обсуждали, когда разбирали «философию Unix» вместе с принципами KISS.
    • Открытости/закрытости (OCP). Компоненты — расширяемые и немодифицируемые. Его основоположником считают Бертрана Мейера (Bertrand Meyer) — автора Eiffel.
    • Подстановки (LSP). Разработчик должен иметь возможность заменить тип на подтип, не сломав систему. Иерархию типов нужно тщательно моделировать, чтобы избежать путаницы. Принцип предложила Барбара Лисков (Barbara Liskov) — один из авторов Clu.
    • Разделения интерфейса (ISP). Роберт Мартин (Robert Martin), международно признанный эксперт в области разработки ПО, определил этот принцип следующим образом: «программные сущности не должны зависеть от методов, которые они не используют». Так можно упростить рефакторинг в случае внесения изменений в логику работы ПО.
    • Инверсии зависимостей (DIP). Управляющие компоненты должны быть абстрагированы от модулей нижних уровней, а детали — не зависеть от абстракций и модулей верхних уровней. Роберт Мартин предложил и этот пункт (вот текст его оригинальной публикации).

    Если следовать этому и структурировать классы и функции так, чтобы SOLID-принципы выполнялись, можно с высокой вероятностью получить надежный, понятный и легко поддерживаемый код. Кстати, здесь есть примеры, иллюстрирующие работу каждого из принципов.

    Кто вывел SOLID


    Как вы уже успели догадаться, за основную часть принципов отвечал именно Дядя Боб. Комплексно он описал их в работе «Design Principles and Design Patterns» 2000 года, а сам акроним SOLID уже позже предложил инженер Майкл Фэзерс (Michael Feathers). Если интересно, у Майкла есть книга, где он дает рекомендации о том, как «оживить» legacy-систему и не сойти с ума по ходу дела.


    Фото — Oskar Yildiz — Unsplash

    Задача SOLID — способствовать разработке приложений, которые легко поддерживать и расширять в течение долгого времени. Но этот свод рекомендаций часто подвергают критике.

    За что критикуют


    Иногда эти принципы называют «слишком расплывчатыми», что усложняет их практическое использование. Программист и писатель Джоэл Спольски (Joel Spolsky) в одном из выпусков The StackOverflow Podcast также отметил, что SOLID-методология слишком утопична и вынуждает разработчиков тратить время на избыточный код фактически «ради галочки».

    Он считает, что не нужно заранее пытаться учесть все возможные варианты развития событий и просто программировать, постепенно исправляя недочеты, а не опираться на мнимую «систему безопасности». Спольски не отменяет значимости принципов, но называет их чрезмерными.

    Есть мнение, что SOLID-код имеет слабую связность и его легко тестировать, но очень сложно понимать (в критике используется слово «unintelligible»). Программисту приходится писать множество детализированных интерфейсов и небольших классов, которые больше отвлекают и путают, чем помогают наладить какую-то систему. С этим утверждением соглашаются многие, кто считает, что достаточно фокусироваться на простоте кода, чтобы его могли поддерживать другие разработчики.


    Фото — Kevin Canlas — Unsplash

    В тематическом треде на Hacker News говорят и о том, что гораздо большее значение имеет выбор архитектуры, технологического стека и управление зависимостями проекта, а не основополагающие принципы, по которым строится его написание. Здесь вновь указывают на излишнюю сложность старта с комплексного проектирования системы, указывая уже на принцип YAGNI или «You aren't gonna need it». В какой-то степени это — очередной ремикс классического KISS-подхода.

    Стоит признать, что есть и множество высказываний в защиту SOLID. Так, один из резидентов HN говорит, что следование эти принципам поможет быстро заменить условную библиотеку, если на уровне абстракции что-то пойдет не совсем так. Достаточно будет удостовериться в выполнении тестов для новой реализации и на этом все, максимум — дополнительно проверить зависимости для старой версии класса и по мере необходимости использовать доработанный, чтобы тесты прошли успешно. Тогда в коде не будет и «излишней сложности», а тем, кто будет заниматься им впоследствии, не будет грозить так называемый синдром неприятия чужой разработки.

    Важно помнить, что принципы SOLID являются лишь рекомендациями, а не строгими правилами. И всегда будут кейсы, когда их лучше придерживаться, а когда — отступить.



    О чем мы пишем в корпоративном блоге 1cloud.ru:

    Необычные приглашения на собеседование — от HTTP-заголовка до сообщения в поисковике
    Почему разработчики дороже денег, как их сохранить и приумножить
    Группа разработчиков предлагает перейти на UTF-8



    Новые публикации у нас на Хабре:



    1cloud.ru
    IaaS, VPS, VDS, Частное и публичное облако, SSL

    Комментарии 11

      +3
      Я уважаю практичные подходы к написанию статей, минимализм и все такое, но ваша статья уж больно коротка.
        0
        Спасибо за конструктивную критику, расширили материал, хотя формат справочный (стараемся его не раздувать — вот пара примеров из нашего блога: 1, 2, 3)
          +1
          Угу. Убрали статью вместе с моим комментарием, и опубликовали снова. Но лучше-то не стало:

          Разделения интерфейса (ISP). Специализация, чтобы развязать их и программные сущности, плюс — упростить рефакторинг.


          «Чтобы развязать их» — их это кого? Ну ок, про UI убрали, но все равно видно невооруженным глазом, что копирайтер (пардон за матерное слово) не понимает тут вообще, о чем пишет.
            +1
            Если чуть сбавить обороты и вики открыть залинкованный в посте, то особых проблем нет с предложенной формулировкой: «Принцип разделения интерфейсов говорит о том, что слишком «толстые» интерфейсы необходимо разделять на более маленькие и специфические, чтобы программные сущности маленьких интерфейсов знали только о методах, которые необходимы им в работе».
              +1
              Я формулировку из поста дословно процитировал. Более того, это уже вторая ипостась данного поста, к первой был мой же комментарий, к этой же фразе. Потому что в первой ипостаси в этой же формулировке упоминался UI, при том что данный принцип ISP не имеет к нему никакого отношения.
                +4
                Спасибо за критику. Ошибка действительно имела место быть, поправили этот момент, плюс — решили немного расширить материал.
                  +1
                  Это приятно, когда коопоративные блоги реагируют на критику. Не, реально, даже когда обижаются. Многие вообще не реагируют, и от них комментариев не дождешься.

                  Опечатку-то все-таки поправьте пожалуйста. Она же все равно там осталась.

                  >Специализация, чтобы развязать их и программные сущности
                  Тут не хватает слова, которое обозначено местоимением «их». Специализация кого? Непонятно.
          +1

          Мне больше интересно, в чём отличие этой статьи от множества остальных.


          Почему я не преподаю SOLID и «принцип устранения зависимостей»
          Шпаргалка по SOLID-принципам с примерами на PHP
          Разбираемся с SOLID: Инверсия зависимостей
          SOLID: принцип единственности ответственности
          Принципы SOLID в действии: от Slack до Twilio
          Простое объяснение принципов SOLID
          Очень простое объяснение принципов SOLID
          SOLID
          Принципы SOLID, о которых должен знать каждый разработчик
          ООП, «святая троица» и SOLID: некоторый минимум знаний о них
          Пишем гибкий код, используя SOLID
          Применение принципов SOLID при разработке React-приложений
          Принципы SOLID в картинках
          Принцип SOLID в языке Go


          Критика SOLID — отлично. Но хотелось бы больше конструктива.
          Например, я считаю, что любой разработчик неявно к этим принципам и приходит — сами инструменты (ООП, юнит-тесты) вынуждают его писать код в соответствии с этими принципами.

            +3
            Такой вопрос можно задать к любой статье, при особом желании сослаться на принцип «это уже было в Симпсонах». Если тему поднимают вновь, значит, есть о чем поговорить, а до обсуждения разных точек зрения неплохо напомнить основную суть вопроса.

            Если говорить о критике и мнениях в защиту, то как раз в комментариях (на Хабре и на Hacker News условном) зачастую гораздо больше пользы чем в любом справочном формате. Люди личным мнением делятся, как вот вы сейчас сами и поступили, что весьма ценно. Спасибо!
          +3
          Но зачем, зачем в сотый раз писать про SOLID? Про SOLID, про который даже на Википедии можно прочитать!
            +3
            Так этож корпоративный блог, неважно что писать, важно быть на виду.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое