Борьба со сложностью

Сложность это плохо

Влияние сложности

«Простота — это душа надёжности», — Эдсгер Дейкстра

«Если мы посчитаем количество строк кода, то стоит рассматривать их не как «произведённые строки», а как «строки потраченные», — Эдсгер Дейкстра.

«Код легче писать, чем читать», —  Джоэл Спольски.

«Любой дурак может написать код понятный для компьютера. Хорошие же программисты пишут код, который смогут понять люди», —  Мартин Фаулер

»Любая работоспособная сложная система является итогом эволюции более
простой работоспособной системы… Сложная система, разработанная «с нуля»,
никогда не работает так, как надо и никакие «заплатки» не заставят ее работать
правильно. Проектирование следует начинать с простой работоспособной
системы
 — Буч Г.

Сложность ведет к превышению плановых трудозатрат, времени, переработкам и выгоранию. В начале проекта сложности не видно. Разработчики склонны выкинуть все старое и переписать заново, что может пойти не так? Согласно данным, приведенным в книге Роберта Мартина «Чистая архитектура» с ростом сложности резко растет стоимости доработки каждой новой фичи.

Психологические трудности

Обосновать высокие трудозатраты (что может пойти не так?) трудно и себе то, а другим и подавно. Разработчик может дать обещания сделать задачу в излишне оптимистичные сроки. Дальше обязательно возникают непредвиденные трудности и переработки. «Ну ты что же, непрофессионал, задача то простая?» — опасный психологический феномен, даже если не давит заказчик или руководитель. Давит твое эго.

5f6530c5c83de0fc79c21a1217d0ecfd.png

Типы сложности

Внутренняя сложность задачи (inherent complexity) и непреднамеренно привнесённая сложность (accidental complexity).

Типичная ловушка, с которой мы сталкиваемся в процессе проектирования ПО, проявляется в фокусировании на том, насколько «простым» является для нас чтение и понимание конкретного фрагмента кода. Однако фокусирование на простоте чревато множеством затруднений, поскольку сложность не может быть удалена: она может быть только перемещена. Если вы её перемещаете из своего кода, куда она тогда денется?

Отведите ей подобающее место и изолируйте ее.

Катастрофа, все пропало!

Катастрофа, все пропало!

Если сложность реализации значительно больше чем сложность описания это тревожный звоночек.

Если листинг кода в 10+ раз больше чем описание задачи, задумайтесь: что-то здесь не так, вы упоролись! Но это не точно.

Если листинг кода в 10+ раз больше чем описание задачи, задумайтесь: что-то здесь не так, вы упоролись! Но это не точно.

Ментальные ограничения

»Я не буду думать об этом сегодня,  я подумаю об этом завтра» Скарлетт о Хара.

При продумывании программы думайте сконцентрируйтесь на нужном. Поскольку все в голове не помещается ненужные сейчас детали должны вытесняться из сознания.

Когда программа создается специалист может удержать сразу несколько предметных областей и пишет все подряд (программирование снизу вверх — «просто взять и написать»).

Когда программа читается, то неподготовленный (а так обычно и бывает) читатель может удержать в голове одновременно лишь одну предметную область. Здесь требуется программирование сверху вниз — «хватит лить воду, ты мне мясо давай!»). Код читается втрое чаще чем пишется, поэтому после написания простого кода и проверки вариантов реализации код нужно причесать, провести рефакторинг. Когда система выходит из состояния стартапа нужно провести рефакторинг снова.

Хватит лить воду, ты мне мясо давай!

Хватит лить воду, ты мне мясо давай!

Методы измерения и контроля сложности

Декомпозиция и отладка по частям, уменьшение числа связей:

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

  • Отладка и тестирование каждого модуля по отдельности.

Композиция проверенных деталей проверенным способом:

  • Использование простых, проверенных способов объединения модулей, например, чистые функции.

Абстракция:

Инкапсуляция:

  • Защита от «прорыва сложности» за пределы одного модуля в другие

  • Ограничение доступа к внутренним деталям реализации модулей ради безопасности.

Эволюционное наращивание сложности:

  • Постепенное добавление новой функциональности с уточнением требований

  • Уточнение границ модулей и ужесточение правил (границ)

Баланс между быстро и правильно

Нужно просто писать код так же естественно как описывать проблему собеседнику — до тех пор пока ментальная сложность создания и чтения не превысит порога когда имеет смысл рефакторинг кода. Рефакторинг должен быть простой и естественный как дыхание.

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

Что на практике?

А на практике были случаи когда я писал код в 10(!) раз более краткий и понятный чем у соседа по цеху.

И вот как я вижу чужой переусложненный код

В видео объясняется, как различные сервисы, такие как бинго, papaya, mbs, ulna, raccoon, wingman, rgs, barbie doll, ringo two, bls и «галактус», работают вместе для предоставления информации о пользователях.

«Галактус» — это всезнающий агрегатор, который собирает информацию от других сервисов и предоставляет ее ведомым.

Не делайте так!

© Habrahabr.ru