Развитие путем очистки

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

Что сложного в программном обеспечении — ПО, которое поставляется и имеет ценность для пользователей, — это не проблема реализации одной функции. Всегда есть способ собрать воедино то, что вы хотите, на таком низком уровне сложности, и часто он вообще не требует программного обеспечения. Проблема заключается в том, что несколько функций складываются в предполагаемый дизайн. Путь, выбранный большинством разработчиков, когда они вынуждены работать в условиях жесткого графика, заключается в том, чтобы найти способ взломать его, спроектировать программное обеспечение так, как все хотят, чтобы оно было разработано: с помощью собираемых вместе кубиков Lego, будь то функции, классы, модули или пакеты. И, следовательно, быть умным и нетерпеливым, и быть более умным, потому что вы более нетерпеливы. И найти более эффективные способы взлома, чтобы вы могли дольше избегать последствий. И это движет большинством контента в блогах.

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

А теперь я возвращаюсь ко всем тем техническим блогам, которые читал. Очень многие из них следуют, в широком смысле, формулировке «этот странный трюк — хорошая идея», которая все чаще становится своего рода красным флажком в моей голове. Если у вас есть какой-то странный трюк, и вы не критикуете этот трюк и его ограничения и не стараетесь указать на них, вы все равно грубо его используете. Вы можете не знать, что это грубо, потому что культура, вероятно, настолько погружена в это, что тавтологически предполагает, что практика хороша. Но единственная причина, по которой кто-то использует один странный трюк, я думаю, сводится к тому факту, что не появилось ничего лучше, что было бы одновременно эффективным и простым в смысле Рича Хики «доступным, под рукой», и его легко получить. увязли в причуде карго-культа, которая позиционирует себя как эффективная и простая, и еще проще придерживаться этой причуды, несмотря на ее недостатки, когда вы по той или иной причине не контролируете проект.

Так что же вы делаете вместо одного странного трюка? Если объектно-ориентированное программирование не спасет вас, и метапрограммирование шаблонов не спасет вас, и предметно-ориентированные языки не спасут вас, и функциональное программирование, и разработка через тестирование, и гибкая разработка программного обеспечения, и любая другая практика, которую вы хочешь назвать?

Вот что я начал делать. Я убираю вещи, и мой процесс — это процесс очистки. Уборка скучна, жестока и не обещает облегчения жизни. Я программист во втором поколении, и мой дорогой старый папа сказал по этому поводу: «Я больше похож на уборщика программного обеспечения, чем на кого-либо еще — я убираю беспорядок». Всё чаще приходится соглашаться. Если это мой код, то это мой беспорядок; если это чужой код, то это все равно мой бардак, и точно так же, даже если я никогда не видел кода и являюсь просто пользователем. Кто-то где-то в конце концов взорвется.

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

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

Как правило, первый шаг в использовании заключается в том, чтобы сделать код менее умным, чтобы вы могли построить именно ту абстракцию, которая вам нужна. Под менее умным я подразумеваю: использует меньше языковых возможностей, использует более распространенные формы абстракции, использует строго менее мощные конструкции, использует меньше косвенности. Если код начинается уже навороченным, напичканным удобствами, которые выглядели хорошо в то время, он слишком сложен, чтобы правильно понять, о чем он. Чтобы получить правильную абстракцию, вы должны сначала уметь видеть.

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

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

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

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

Если вы выдержите это, вы получите золотой самородок в самом конце, где вы создадите действительно глубокое и долговременное архитектурное изменение. Размер кода уменьшается в несколько раз, или вы можете превратить большую часть приложения в прецедент для библиотечного кода. И тогда вы либо уезжаете в закат, либо добавляете больше функций и повторяете процесс. (Вы также обнаружите, что другие программисты каждый раз, когда вы пытаетесь описать то, что вы сделали, говорят, что он «слишком сложный», вплоть до того момента, когда они обнаруживают, что хотят использовать ваш код. Улыбайтесь и подбадривайте их.)