Есть два типа языков: языки, где есть только один очевидный/правильный путь реализовать что-либо (Python, Java), и языки, где одну и ту же фичу можно закодить тысячей и одним способом (C++, JavaScript, Ruby). Первые больше похожи на детские конструкторы, вторые - на пластелин.

Подробнее LEGOs, Play-Doh, and Programming и инфографика.

И если для первой группы языков имеет смысл перерывать StackOverflow в поисках единственно-истинного решения отсортировать массив, то для второй группы обычно существует сразу множество "верных" решений. Зачастую, эти решения даже не являются компромиссными. Т.е. с точки зрения скорости выполнения, используемой памяти, поддержки кода и других аспектов абсолютно все равно, какое из решений выбрать.

How Robusta makes Kubernetes operation better for everyone:

  1. You run into a failure scenario and write an alert & Robusta runbook.
  2. The same scenario happens again but in a different setup. You adapt the runbook
    ...and contribute it back to Robusta so that others could use it too!
  3. You change teams, departments, companies but your best runbooks stay with you -
    they are now a part of the standard Robusta distribution! Win-win! 🖤

Go check it out!

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

Решение, на мой взгляд, состоит в том, что для языков второго типа необходимо "освободить" свой мозг и просто позволить ему творить. Принять для себя, что главное - это написать рабочее решение. Конечно, в процессе разработки будут попадаться не совсем "те" решения, но со временем они будут "выправлены" возникающими неудобствами/противоречиями. И хотя это означает, что часть кода все же придется переписывать - эти переписывания будут обусловлены реальными требованиями (в отличие от циклических переписываний в процессе поиска идеального варианта). Существует и эффективный способ как можно скорее обнаружить неудачное решение - написание тестов. Если код трудно оттестировать - это верный признак неудачного архитектурного решения.