О релевантности принципов объектно-ориентированного программирования SOLID

Сегодня принципы SOLID остаются такими же релевантными, как в 90-е годы и раньше. Это связано с тем, что программы практически не изменились за эти годы. Более того, программы сильно не изменились с 1945 года, когда Алан Тьюринг написал первые строки кода для электронного компьютера. Программы всё ещё состоят из операторов if, циклов while и операторов присваивания. Это всё ещё последовательность, перебор и итерация.

Каждому новому поколению нравится думать, что его мир сильно отличается от мира, в котором жили предыдущие поколения. Это ошибка, которую совершает каждое поколение. Оно осознаёт эту ошибку, когда появляется следующее поколение, которое приходит и рассказывает, как сильно всё вокруг изменилось.

Давайте рассмотрим каждый принцип и оценим его актуальность.

Принцип единственной ответственности

Держите вместе сущности, которые меняются по одной причине. Разделяйте сущности, которые меняются по разным причинам.

Сложно представить, что этот принцип стал нерелевантным. Мы не смешиваем код, который отвечает за бизнес-логику, с кодом, который отвечает за интерфейсы. Мы не смешиваем SQL-запросы с протоколами передачи данных. Мы разделяем код, который меняется по разным причинам, благодаря чему изменения в одной подсистеме не влияют на другие подсистемы. Мы следим, чтобы модули, которые меняются по разным причинам, не влияли друг на друга.

Микросервисы не решают эту проблему. Если вы смешиваете код, который меняется по разным причинам, то можете получить запутанные микросервисы или даже наборы запутанных микросервисов.

Слайды Дэна Норта, ссылка на которые приводится выше, не учитывают этого момента. Из-за этого мне кажется, что он вообще не понимает принцип единственной ответственности, или что он иронизировал. Насколько я знаю Дэна, последнее очень вероятно. В ответ на упоминание принципа единственной ответственности он предлагает писать простой код. Я согласен с этим. Принцип единственной ответственности — один из способов писать простой код.

Принцип открытости-закрытости

Модуль должен быть открыт для расширения, но закрыт для модификации.

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

Или… Хотим ли мы отделять абстрактные концепции от конкретных понятий? Хотим ли мы отделять бизнес-логику от небольших деталей, связанных с интерфейсами, или от протоколов передачи данных, или произвольного поведения базы данных? Конечно да!

И снова в слайдах Дэна Норта есть ошибка. При изменении требований только часть существующего кода становится неактуальной. Но значительная часть кода остаётся актуальной. И мы хотим знать, что нам не придётся менять работающую часть кода только для того, чтобы неработающий код снова заработал. Дэн снова предлагает писать простой код. И я снова соглашаюсь. Соблюдение принципа открытости-закрытости помогает писать простой код.

Принцип подстановки Лисков

Если программа использует интерфейс, она не должна знать о реализации этого интерфейса.

Люди, и я в том числе, долгое время ошибались, думая, что принцип подстановки Лисков применим только к наследованию. Это не так. Этот принцип определяет использование подтипов.

Все реализации интерфейса являются подтипами этого интерфейса. Все утиные типы относятся к подтипам подразумеваемого интерфейса. А каждый пользователь базового интерфейса должен принимать значение этого интерфейса. Если реализация мешает пользователю базового типа, количество конструкций if/switch в коде растёт.

Принцип подстановки Лисков говорит о необходимости чётко определять абстракции. Невозможно поверить, что этот принцип устарел.

В этом случае Дэн и его слайды правы. Он просто упустил из виду детали: простой код — это код, в котором чётко выделены абстракции.

Принцип разделения интерфейса

Делайте интерфейсы маленькими, чтобы клиенты не зависели от вещей, которыми они не пользуются.

Мы всё ещё работаем с компилируемыми языками. Мы всё ещё зависим от дат модификации, с помощью которых определяем, какие модули нужно перекомпилировать и повторно задеплоить. Пока это так, придётся сталкиваться с проблемой зависимости модуля A от модуля B во время компиляции, а не во время выполнения, поскольку изменения в модуле B приведут к перекомпиляции и повторному деплою модуля A.

Эта проблема стоит особенно остро в языках со статической типизацией, например, Java, C#, C++, Go, Swift и так далее. Языки с динамической типизацией подвержены этому в гораздо меньшей степени, но всё-таки полностью не защищены от этой проблемы. Это доказывает существование таких инструментов, как Maven и Leiningen.

Слайд Дэна, посвящённый этому принципу, содержит явно неправильную информацию. Клиенты однозначно зависят от методов, которые не используют, если они нуждаются в перекомпиляции и повторном деплое, когда эти методы меняются. Финальное замечание Дэна здравое, насколько это возможно. Да, если вы можете разделить класс с двумя интерфейсами на два класса, сделайте это. Это соответствует принципу единой ответственности. Но такое разделение часто невозможно и даже нежелательно.

Принцип инверсии зависимостей

Модули верхнего уровня не должны зависеть от деталей реализации модулей нижнего уровня.

Трудно представить архитектуру, в которой не используется этот принцип. Мы не хотим, чтобы высокоуровневая бизнес-логика зависела от деталей реализации на нижних уровнях. Я надеюсь, что это очевидно. Мы не хотим, чтобы вычисления, которые приносят нам деньги, смешивались с SQL-запросами, низкоуровневой валидацией или форматированием.

Мы хотим изолировать высокоуровневые абстракции от низкоуровневых деталей. Это разделение возможно благодаря корректному управлению зависимостями внутри системы. Это управление позволяет всем зависимостям в исходном коде, особенно пересекающим архитектурные границы, указывать на высокоуровневые абстракции, а не на низкоуровневые детали.

Слайды Дэна каждый раз заканчиваются призывом писать простой код. Это хороший совет. Но если годы развития индустрии чему-то нас научили, так это тому, что простота требует дисциплины, которая возможна благодаря принципам. Это те самые принципы, которые определяют простоту. Это та дисциплина, которая заставляет программистов писать простой код.

Лучший способ всё усложнить и устроить беспорядок — просто посоветовать людям писать простой код и ничего больше им не объяснить.

Компания DST Global (dstglobal.ru) предлагает полный набор услуг по разработке заказного программного обеспечения. Проектируем и разрабатываем современное ПО для Интернет-проектов и автоматизации бизнеса.

Мы проектируем качественную, надежную, высокопроизводительную ИТ-инфраструктуру, которая эффективно решает коммерческие задачи и реализуется в соответствии со спецификой Вашего бизнеса.  

Комментарии
RSS
19:14
+2
Интересно по вашему мнению, почему новичкам стоит изучать Java?
Новички выбирают язык для быстрого входа в профессию, и Java соответствует этому критерию. К тому же этот язык не привязывает человека к конкретному узкому направлению, например, фронтенд- или бэкенд-разработке. На Java пишут и фронтенд, и бэкенд, и другие вещи. Например, можно писать приложения для Android.

Java — язык энтерпрайза или больших компаний, это надо учитывать при выборе языка и финансовых перспектив разработчика. Нет компаний, которые не используют Java. Человечество не сможет отказаться от этого языка, так как на нём написано очень много.

Да, Java труднее изучать, чем Python. Порог входа в профессию выше. Но Python не подходит для энтерпрайза, этот язык скорее для более простых вещей, для прототипов.

Надо понимать, что Java — объектно-ориентированный язык. Это может сужать понимание других парадигм. Но Java меняется в сторону поддержки разных парадигм программирования.
19:16
+2
Спасибо за подробный ответ, не подскажите а будет ли по вашему мнению этот язык востребован в будущем?
Попытки вытеснить Java есть. Oracle монетизирует Java, поэтому энтерпрайз будет уходить от этого языка в новых проектах. Например, в мобильной разработке набирает популярность Kotlin, это несложный язык.

Стоит помнить, что Java — язык и виртуальная машина. Виртуальная машина никогда не умрёт. Тот же Kotlin компилируется в байт-код, который исполняет JVM. Да, можно пересесть на Scala, Kotlin, Go. Но в целом непонятно, куда податься с Java и надо ли куда-то подаваться. То есть язык будет востребованным, как минимум будет нужна поддержка того, что уже написано на Java.
19:17
+3
А тогда посоветуйте новичку нужно знать об особенностях Java и направлениях развития этого языка?
Новичок должен понять, какая Java его интересует. Хочет писать мобильные приложения для Android? Это другая виртуальная машина, нужно её изучать. Хочет писать бэкенд? Нужно изучать высокоуровневые фреймворки: Spring, Java EE.

То есть новичку надо выбрать направление, которым он хочет заниматься. Это может быть мобайл или бэкенд. Но базовая Java одинакова для всех.

Ещё надо понимать, что Android отстаёт на несколько версий Java.
Занимательные комментарии, тоже назрел вопрос — если отбросить маркетинговые обещания, сколько времени придётся учиться с нуля до уровня джуниора?
Надо понимать, что интервью джуниора — это в общем случайность. Нет стандартов таких интервью. Обычно собеседование проводит мидл или даже такой же джун. Он задаёт каверзные вопросы и просит решить задачи. Если человек вчера посмотрел урок, связанный с вопросом или с задачей, он всё решит.

Итак, считаю собеседования необъективными, а их результат случайным. Потенциальный кандидат может увеличить вероятность успеха. Для этого надо учиться, учиться и ещё раз учиться.

Некоторым людям для обучения нужны годы, некоторые справляются за 2 месяца. Чётко определённого времени нет. В среднем на обучение уходит полгода. Или 2-3 месяца обучения фултайм.

Ключ к успеху — практика, свои проекты, опенсорс. Также надо знать английский язык.

Если нужен быстрый вход в разработку, надо изучать Java и делать Android-приложения. Такую возможность сложно найти в других направлениях.
19:25
+1
Новичкам нужно начинать с основ — с алгоритмов и структур данных. Язык вторичен, но если основа есть, не составит труда выучить любой. Для кругозора стоит пожалуй разбираться в нескольких языках. Новичкам рекомендую ознакомиться с C/LISP/Java/Python. А далее уже понять к чему больше душа лежит.
Вам может быть интересно
Зачем использовать TypeScript для своих проектов? Основная цель TypeScript — повысить производительность при разработке сложных приложений, а также облегчить жизнь вашей команде при написании ко...
Прочтите это руководство от разработчиков DST Global и узнайте : какая мощная пл...
Ознакомьтесь с подробностями методологий разработк...
Прочтите это руководство от специалистов DST Globa...
Как работает веб?В этой статье разработчики DST Gl...
Рассказываем, зачем и где учить PHP, где его приме...
Современные сайты интерактивные и динамичные &m...
В Последние годы Web-приложения постепенно вытесня...
По результатам ежегодного отчёта State of the Octo...
Java virtual machine (JVM) — это программа, ...
Неопытные разработчики вряд ли поймут, что изображ...

Новые комментарии

Инвестировать в нишевые маркетплейсы не поздно. Наоборот, инвестировать в них сейчас самое время. Потому что покупатели привыкли покупать в интернете,...
Совершенно очевидно что этот год за нишевыми маркетплейсами. Последние несколько лет на рынке постоянно обсуждают нишевые маркетплейсы. Это активно ра...
А почему kafka с databricks не подходит? Hdfs вы имеете в виду не в облаке, а в в своих датацентрах?
Если выбирать DB as a Service, то Snowflake — отличный конкурент Redshift, BigQuery. Если же надо развернуть BigData кластер в облаке, то здесь Databr...

Заявка на услуги DST

Наш специалист свяжется с вами, обсудит оптимальную стратегию сотрудничества,
поможет сформировать бизнес требования и рассчитает стоимость услуг.

Адрес

Россия, Ижевск, ул.Салютовская,
д.1, офис 17

8 495 1985800
Заказать звонок

Режим работы: Пн-Пт 10:00-19:00

info@dstglobal.ru

Задать вопрос по почте

Укажите ваше имя
Укажите ваше email
Укажите ваше телефон