Антипаттерналии I. О конструктивной и деструктивной лени

...или «Не трогай то, что работает» vs «Не ремонтируй то, что не сломано»

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

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

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

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

Обычно, когда разработчик объясняет менеджеру порочность данного подхода, тот ему отвечает: «Это ведь займет слишком много времени! С другой стороны, старый код ведь работает, с чего ты взял, что проблема именно в нем? Нет, лучше адаптируй новый код так, чтобы все работало. Это займет не так много времени.»

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

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

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

Как соотнести наш пример с программным обеспечением?

Если слово workaround применяется в контексте компонентов, не разработанных третьей стороной, то разрабатываемое ПО сломано. Если при добавлении четвертого компонента первый перестает работать, как описано, он сломан. Если у объектов различное представление об общей модели данных, с которой все они работают, они сломаны. Если нужно поднять годичной давности собственный код, и нужно долгое время разбираться, как же он работает, то он сломан.

А сломанное нужно ремонтировать, не так ли?

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

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

Маєте важливу новину про українське ІТ? Розкажіть спільноті. Це анонімно.І підписуйтеся на Telegram-канал редакції DOU

👍НравитсяПонравилось0
В избранноеВ избранном0
Подписаться на автора
LinkedIn



Підписуйтесь: Soundcloud | Google Podcast | YouTube


7 комментариев

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

Во всем должно быть рациональное зерно. Писать надо изначльно красиво, аккурано и гибко, чтоб потом изменения вностились с минимальной кровью. С другой стороны не всегда рефакторинг полезен — лично принимал участие в проектах, написанных мной же, но очень давно, где надо было просто поддерживать систему и ее развития в будущем не предвиделсь. Если рефакторинг и производился то локальный. У КАЖДОГО ПРОЕКТА ЕСТЬ СВОЕ ВРЕМЯ ЖИЗНИ! После этого он навсегда умирает и ему на смену приходит абсолютно новый, более новый, навороченный и изящный. С программистами таже беда, что и с всем извесным художником, которого не пускали на свою же собственную выставку с красками и кистью, что б он там часом ничего не подправил. Каждый менеджер должен чувствовать момент, после которого он должен сказать — «Стоп! На этом мы ставим точку.» Зачастую например более продвинутые и изящные решения для часто-повторяемой проблемы (патерн) лучьше не вносить в написанный и работающий проект, если старый патерн работает без нареканий. Это может вообще развалить проект, т к новое решение не оттестировано к томуже не вписывается в целостную архитектуру устаревшей системы, что внесет хаус. А вот старое работает годами, вписывается в архитектуру и есть куча народу которые знают как его использовать и чинить. поэтому доля консерватизма в принячтии решений по рефакторингу должна присутсвовать. Не забывайте в конце концов что за все это комуто придется платить...Так что

«Чинить пока не сломается» — это уже не разработка ПО

Это скорее удовлетворение своего «я». Раз я не поковырялся в коде, значит, код плохой. Исправить надо. У всех код sucks, кроме меня.

как же эта ситуацию знакома: (

По-моему, это часть опыта разработчика ПО — понимать, когда следует рефакторить, а когда нет.

Можно долго обсуждать меру полезности/эффективности конкретного рефакторинга в конкретном проекте на конкретном этапе

Ну, про це можна з десяток статей написати, до речі, планується.

Если кратко — «Рефакторинг полезен»:) Ни одна статья, развивающая данный тезис не даст ровным счетом ничего, если именно этот тезис считают неправильным/противоречивым/неактуальным/небезопасным. «Считают» означает «считает кто-то из участников проекта, и никто другой ему не прочищает мозги по этому поводу». И неважно кто это — разработчик, менеджер, представитель заказчика, инвестор... Важно то, что: А. Он ошибается.Б. Ему это разрешают делать.Можно долго обсуждать меру полезности/эффективности конкретного рефакторинга в конкретном проекте на конкретном этапе. И даже если рефакторинг громадного куска кода на выходе дал тот же результат, никто не отнимет опыта, который получит разработчик:) «Чинить пока не сломается» — это уже не разработка ПО, и за такое никто, в конце концов, денег платить не будет. Так что рано или поздно каждый разработчик/менеджер/заказчик находит для себя ту меру, которая определяет его понимание полезности/эффективности рефакторинга (опять же, в конкретных условиях). Лучше, если рано:)

Очень правильно все написано. Я бы добавил, что рефакторить нужно периодически хотя бы для того, чтобы не забывать, как там все внутри устроено.:) Главное перебороть страх изменений — с системой контроля версий, в случае чего, все можно отрефакторить назад в два счета:)

Подписаться на комментарии