Сложность это плохо
Влияние сложности
“Простота — это душа надёжности”, — Эдсгер Дейкстра
“Если мы посчитаем количество строк кода, то стоит рассматривать их не как “произведённые строки”, а как “строки потраченные”, — Эдсгер Дейкстра.
“Код легче писать, чем читать”, — Джоэл Спольски.
“Любой дурак может написать код понятный для компьютера. Хорошие же программисты пишут код, который смогут понять люди”, — Мартин Фаулер
“Любая работоспособная сложная система является итогом эволюции более
простой работоспособной системы… Сложная система, разработанная «с нуля»,
никогда не работает так, как надо и никакие «заплатки» не заставят ее работать
правильно. Проектирование следует начинать с простой работоспособной
системы.” — Буч Г.
"Инженер - такой человек, который с легкостью превратит простую проблему в сложную, а потом решит её через задницу" — народное.
Сложность ведет к превышению плановых трудозатрат, времени, переработкам и выгоранию. В начале проекта сложности не видно. Разработчики склонны выкинуть все старое и переписать заново, что может пойти не так? Согласно данным, приведенным в книге Роберта Мартина "Чистая архитектура" с ростом сложности резко растет стоимости доработки каждой новой фичи.
Психологические трудности
Обосновать высокие трудозатраты (что может пойти не так?) трудно и себе то, а другим и подавно. Разработчик может дать обещания сделать задачу в излишне оптимистичные сроки. Дальше обязательно возникают непредвиденные трудности и переработки. "Ну ты что же, не профессионал? Задача то простая!" - опасный психологический феномен, даже если не давит заказчик или руководитель. Давит твое эго.
Типы сложности
Внутренняя сложность задачи (inherent complexity) и непреднамеренно привнесённая сложность (accidental complexity).
Типичная ловушка, с которой мы сталкиваемся в процессе проектирования ПО, проявляется в фокусировании на том, насколько "простым" является для нас чтение и понимание конкретного фрагмента кода. Однако фокусирование на простоте чревато множеством затруднений, поскольку сложность не может быть удалена: она может быть только перемещена. Если вы её перемещаете из своего кода, куда она тогда денется?
Отведите ей подобающее место и изолируйте ее.
Если сложность реализации значительно больше чем сложность описания это тревожный звоночек.
Ментальные ограничения
"Я не буду думать об этом сегодня, я подумаю об этом завтра" — Скарлетт о Хара.
При продумывании программы думайте сконцентрируйтесь на нужном. Поскольку все в голове не помещается ненужные сейчас детали должны вытесняться из сознания.
Когда программа создается специалист может удержать сразу несколько предметных областей и пишет все подряд (программирование снизу вверх - "просто взять и написать").
Когда программа читается, то неподготовленный (а так обычно и бывает) читатель может удержать в голове одновременно лишь одну предметную область. Здесь требуется программирование сверху вниз - "хватит лить воду, ты мне мясо давай!"). Код читается втрое чаще чем пишется, поэтому после написания простого кода и проверки вариантов реализации код нужно причесать, провести рефакторинг. Когда система выходит из состояния стартапа нужно провести рефакторинг снова.
Методы измерения и контроля сложности
Декомпозиция и отладка по частям, уменьшение числа связей:
Разбиение системы на более мелкие, независимые модули, тогда сложность, т.е. количество связей будет равна сумме сложностей компонентов, а не факториалу их числа в случае связей "все зависит от всего"
Отладка и тестирование каждого модуля по отдельности.
Композиция проверенных деталей проверенным способом:
Использование простых, проверенных способов объединения модулей, например, чистые функции.
Абстракция:
Ментальная инкапсуляция, скрытие деталей реализации и представление только необходимой информации.
Инкапсуляция:
Защита от "прорыва сложности" за пределы одного модуля в другие
Ограничение доступа к внутренним деталям реализации модулей ради безопасности.
Эволюционное наращивание сложности:
Постепенное добавление новой функциональности с уточнением требований
Уточнение границ модулей и ужесточение правил (границ)
Баланс между быстро и правильно
Нужно просто писать код так же естественно как описывать проблему собеседнику - до тех пор пока ментальная сложность создания и чтения не превысит порога когда имеет смысл рефакторинг кода. Рефакторинг должен быть простой и естественный как дыхание.
Вот пара примеров, когда погоня за "правильным кодом приводит к ужасным последствиям"
Что на практике?
А на практике были случаи когда я писал код в 10(!) раз более краткий и понятный чем у соседа по цеху.
И вот как я вижу чужой переусложненный код
В видео объясняется, как различные сервисы, такие как бинго, papaya, mbs, ulna, raccoon, wingman, rgs, barbie doll, ringo two, bls и "галактус", работают вместе для предоставления информации о пользователях.
...
"Галактус" - это всезнающий агрегатор, который собирает информацию от других сервисов и предоставляет ее ведомым.
Не делайте так!
Комментарии (10)
AlexunKo
14.05.2024 18:11+5Не хочется расстраивать автора что сложность и переусложненность - две большие разницы. Это как при переедании бороться с пищей.
TerraV
14.05.2024 18:11+2Разработка через управление сложность - это мое хобби последние лет 5. В среднем мне это дает производительность х4 по сравнению с моими коллегами, плюс очень малое падение скорости разработки на длинном этапе. А в легаси проектах даже прирост скорости (за счет попутного рефакторинга на обычных задачах).
Я для себя сформулировал следующие подходы для минимизации сложности:Единообразие
Минимизация сторонних библиотек
Минимизация слоев абстракции
Минимизация наследования
Изучение и совершенствование базовых технологий, а не производных (совершенствовать SQL лучше чем совершенствовать ORM)
Domain Driven Design
Управление границами
Управления зонами ответственности
kozlov_de Автор
14.05.2024 18:11Слой абстракции полезно вводить как прокладку между программистами. Это и зависимости уменьшает и понимание упрощает.
А ещё упрощает изменение кода. Ровно до тех пор пока сами абстракции не придется переделывать.
Одному программисту проще без абстракций.
По сторонним библиотекам недавно удалось обойтись расширениями к функционалу библиотеки (c# extension methods), очень положительный опыт.
Наследование вредно потому что зависимость дочернего класса от родительского потом сложно переделать.
"совершенствовать SQL лучше чем совершенствовать ORM" - согласен. Хотя, orm очень неплох для быстрой разработки прототипа.
aamonster
14.05.2024 18:11+1А на практике были случаи когда я писал код в 10(!) раз более краткий и понятный чем у соседа по цеху.
Я правильно понимаю, что сосед думал то же самое про ваш код, потому что место для упрощения в вашем коде видел, а в своём – нет?
kozlov_de Автор
14.05.2024 18:11Он вздыхал и спрашивал: "когда же будет код?")))
Я пишу медленно, а красивая идея мне почти через год в голову пришла
¯\_(ツ)_/¯
bear11
14.05.2024 18:11+1Ха.
"Внутренняя сложность задачи (inherent complexity) и непреднамеренно привнесённая сложность (accidental complexity)."
А еще бывает преднамеренно привнесенная сложность. Например, в Linux привнесли systemd.
kozlov_de Автор
14.05.2024 18:11Да, хотел написать про это
Количество разработчиков UI SnapChat превышает количество кнопок в приложении
Разработчиков набирали чтобы показать инвесторам что это крутая компания
Интервью Дурова Такеру посмотри - то же самое про другие компании говорит.
nikolz
14.05.2024 18:11+2Задача бывает простой в начале и в конце ее решения.
В начале - мы дилетанты, в конце - профи.
-------------------
Следствие:
Если простая задача вдруг стала сложной, то вы на пути ее решения.
Batalmv
14.05.2024 18:11+2Мне кажется, статья несколько ... ни о чем. За все хорошее против всего плохого, без чего-то по сути
--------------------------
В целом ... я даже не скажу, в чем проблема у автора. Читать код - это не самое критичное. Его сложность - тоже.
Куда важнее его сопровождение, т.е. возможность внесения изменение БЕЗ ВЛИЯНИЯ на остальное. Это именно то, что нгапрямую влияет на сроки, риски и деньгию
Простой пример. На "дисковери" разбирали код старого приложения клиента. Это был .NET, в котором я "баран баранчиком", но ... код представлял собой кучу копипейста, вот просто овер до фига, вызов хранимок и SQL прям напрямую, WebForms и т.д.
Код - полное овно, но читался просто прекрасно даже для меня. Все понятно, очевидно. Бизнес логика понятно. Косяки тоже :)
Но сопровождение такого кода - это найтмар. В одном методе в коде меняется визибилити элемента и чего-то запросом пишется в базу, куча "магических констант", повторяемых кусков кода. Что-то менять просто страшно, поэтому пациента приговорили
Но повторюсь - с чтением вообще нет проблем. Как художественную книжку (за ислючением магических констант, тут понятно логика выпадает, и надо просто понять и простить)
Т.е. важна сопровождаемость, а все остальное - уже производные
gleb_l
.https://habr.com/ru/articles/668300/comments/#comment_24386038 - вот один из моих комментов про сложность систем - забавно, все заметно коррелирует