Вот как бывает, пишешь программу, и вдруг видишь, что какой-то кусочек повторяется, и даже не второй раз. Начинаешь понимать, что это кандидат на новую функцию. Не потому, что логика обосабливаемая, а просто потому, что оно повторяется.
Этот кусочек нужно скопипастить, выбрать ему место, подровнять, дать имя этой новорожденной функции, и всем ее параметрам и переменным. Ведь теперь это самостоятельная функция, а не какой-то там временный тестовый код.
И вот получилась маленькая красивенькая функция, которая имеет всего одну функцию, один смысл, одну аккуратную страницу кода. Рекурсия блестит и сверкает своей стройностью и логичностью. В ней ничего лишнего, к ней ничего не нужно добавлять. Пока...
Но проходит день, другой, и начинаешь понимать, что она не так уж и совершенна, что в глубине этой функции нужно добавить еще одно условие. Добавить параметр вызова с лямбдой, в которой бы то условие проверялось бы, обрабатывалось, и т.д. В общем немножко добавить, что бы функция стала немножко более совершенной.
Ну не дублировать же целую страницу кода ради дополнительных двух строк кода? Если на каждое условие делать копии функций, это будут мегабайты однотипного кода.
И теперь в ней появляется дополнительное условие, добавляющее ей универсальности. Казалось бы теперь это само совершенство.
Но время идет, и аппетиты растут. Теперь программа хочет иметь новые свойства, новые условия, которые нужно где-то разместить, где-то поселить...
Ну в самом деле, не копировать же каждый раз функции, ради одного нового маленького-маленького условия? Ему всего то нужно места, две, а может и одна короткая строчка. Может даже всего один оператор умножающий на коэффициент какой-нибудь смысл или возводящий в степень.
И так прошло время, недели или даже месяцы.
Теперь это уже не та маленькая и красивая функция. Теперь это монстр, который может делать все и вся, потрясающий своей красотой в сложных хитросплетениях взаимодействий.
Она не так уж и велика, всего страниц на пять-десять кода. Но в ней все так взаимосвязано, все параметры и переменные так задействованы, каждое написанное слово имеет столько смыслов, тщательно продуманных... и благополучно забытых.
Вокруг, словно пояс астероидов, расположились маленькие функции вспомогательного функционала. Они жмутся к этому монстру, кроме него они никому не нужны, без него их сразу удалят.
Между строк уныло бледнеют старые комментарии, на которые уже давно не смотришь, их словно нет. При попытке их читать, слова кажутся бессвязными и не имеющими отношение к окружающему коду. Но они все равно остаются, в надежде пролить хоть какой-нибудь свет на происходящее.
Все это страшно менять, дабы ничего не рухнуло. Сложно переосмыслить, ведь каждое изменение может откликнуться во многих других местах. Сложно избавиться от всего этого, ведь от этого монстра теперь многое зависит.
И сложно дальше делать программу, этого монстра теперь никуда не подвинуть. Теперь, что бы что-то изменить, нужно убить этого монстра. Пока он не пожрал всю программу.
Убить, мясо разделить на кусочки, и накормить ими новые маленькие функции, новых подрастающих монстриков.
PS: Прототипом к описанию была функция, которая занимает ~3 страницы, с кучей вспомогательных функций, которые все мельче, но суммарно их много.