Pull to refresh

Comments 51

Раньше на Хабре вроде какая-то "песочница" была. Теперь любая банальщина сразу публикуются?

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

Про кофе для программиста уже было

Я работаю в аутсорсе

своему глубокому удивлению, ознакомившись с кодом, я поняла, что его никто не рефакторил весь этот год

вот ни капли не удивлён, никогда клиент не согласует вам 100500 часов на деятельность которая не принесет никакой ценности сиюминутно. Я бы радовался бы чтобы хотябы юниттесты в аутсорсе бы были, куда там про рефакторинг

никогда клиент не согласует вам 100500 часов на деятельность которая не принесет никакой ценности сиюминутно

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

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

если рефакторинг полезен проекту, значит в бизнесе наступила стагнация

Звучит как типичная цыганщина. Почти уверен, что эти мысли ему вложили в голову на трениге успешного успеха.

Звучит как типичная цыганщина.

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

Любая цыганщина в основе своей имеет быстрый рост бизнеса

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

Именно так. А потом один из туземцев понимает, что их "аэропорт" цыганщина и приехав в европу - автоматом называет все аэропорты цыганщиной, лишь потому, что там тоже "не проводят рефакторинг":)

"если рефакторинг полезен проекту, значит в бизнесе наступила стагнация и вместо рефакторинга надо думать об развитии бизнеса".

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

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

Этот код получил право на существование только потому, что разработчику никто не выделил времени на рефакторинг

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

Предлагаете овертаймить на энтузиазме?

Предлагаю овладеть искусством органично вписывать рефакторинг в рабочий процесс. Я не овертаймлю в принципе, но рефакторингом в разных формах занимаюсь постоянно.

То есть за счет заказчика (часы-то оплачивает он) занимаетесь тем, чем хотите вы (раз заказчик не выделил оплаченного времени на рефакторинг). Это всё конечно не ради обмана заказчика и не что бы было приятно работать, а исключительно ради благородной цели создания идеального кода:)

Не, ну серьезно. Заказчик Вам дает задачу - сдать проект как можно скорее, Вы половине времени тратите на рефакторинг и сдаете его со сроком в два раза больше. Может это и хорошо по отношению к коду и следующим программистам, но вот хорошо ли это по отношению к заказчику.

Вы половине времени тратите на рефакторинг и сдаете его со сроком в два раза больше

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

Это ваша фантазия на пустом месте. У вас есть фактура, что конкретно я проваливаю сроки

Не наша фантазия, а Ваша. Мы нигде не говорили, что Вы проваливаете сроки.

Если вы сами не можете рефакторить

Те ошибки, что Вы "рефакторите" изначально не должны были возникать при соблюдении культуры кода и гайдлайнов.

Что-то у вас очень узкий взгляд на рефакторинг, раз вы этим спокойно в разных формах в рабочем процессе постоянно занимаетесь. Либо вы просто держите заказчика за дурачка, которому не нужно знать ничего. "Я занимаюсь непонятной для вас магией, отвалите."

Что-то у вас очень узкий взгляд на рефакторинг, раз вы этим спокойно в разных формах в рабочем процессе постоянно занимаетесь

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

Либо вы просто держите заказчика за дурачка

Я держу заказчика за заказчика. Это такой чувак, который дал бюджет (не моя епархия, слава б-гу), задачу и время. И интересует его только выполнение задачи к указанному времени. Как я буду выполнять эту задачу - ни разу не его дело. Иначе это уже микроменеджмент, который до добра не доводит. А моя работа для него в любом случае магия. Иначе бы он был моим коллегой, а не заказчиком.

Как я буду выполнять эту задачу - ни разу не его дело. Иначе это уже микроменеджмент, который до добра не доводит.

Я, пожалуй, слишком общий термин использовал. Условно говоря, не заказчик, а Product Owner, который заведует общим направлением продукта. В одной фирме PO не вмешивался в техническую часть, он ставил абстрактные задачи и даже выделял время в спринте на различные технические работы.

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

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

Возвращаясь к корневому комменту, мне сложно представить, как я говорю PO, руки прочь от моих задач, это всё моя ответственность. И да, это моя ответственность, что я выбрал эту работу, просто я веду к тому, что, блин, ситуации разные бывают и не везде разработчик бог и я не очень понимаю зачем вы все ситуации под одну гребенку так категорично подводите. Это какое-то игнорирование реальности.

. И интересует его только выполнение задачи к указанному времени. Как я
буду выполнять эту задачу - ни разу не его дело. Иначе это уже
микроменеджмент, который до добра не доводит. А моя работа для него в
любом случае магия. Иначе бы он был моим коллегой, а не заказчиком.

Это вы както совсем на мелком уровне

Бывают заказчики у которых собственный ИТ отдел и компетенции повыше ваших. и как тут рядом писали которые упарываются в бюджеты...я работал на таком проекте, там заказчик (огромная контора с ИТ отделом на десяток департаментов) ревьювил сам каждую задачу и резал часы если сделано чтото свыше того что он просил... типа реализовать фичу N?.окей..тесты написал? выкинуть, мы вам платим за качественную реализацию фичи, а не за написание тестов..вы обещали не косячить... рефакторинг кода в фиче X потому что она рядом? мы за это не платили, вычеркиваем...

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

От таких надо голосовать ногами

не надо вообще идти в аутсорс, там 90% проектов упоротые

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

тем не менее проекты такие есть и будут и много и вы с ними столкнетесь, вечно бегать по мелким конторам ..ну это тоже путь, хотя как по мне он немного тупиковый

От таких надо голосовать ногами.

В нашем мире если от каждого долбо*ба голосовать ногами, то очень скоро не останется места куда этими самыми ногами голосовать.

Я бы предложил сразу делать нормально. А нам не выделили время на рефакторинг, часто синоним "я не знал как сделать нормально и было лень сразу зариматься, сделал как получилось". Мне ту нравится аналогия со строительством, вызвав себе кого-то переложить пол например и даже договорившись по срокам, вы как заказчик будете ожидать что пол будет уложен ровно и качественно. И вы крайне удивитесь если тот кто его вам сделал скажет постфактум-"я тут сделал как получилось, но по хорошему там его ещё выровнять надо, а ещёсне не хватало ламината который вы дали и я нашёл там в углу остатки какого-то другого, и положил его. Ну и что что другого цвета, но вы же не выделили мне время и средства съездить в магазие и докупить? Задача выполнена, ходить можно и пыли нету"

Это ведь всеми любимый принцип KISS, согласно которому: "Сделаем через жо*у кое-как. Потом когда надо будет то выкинем всё нах*й отрефакторим".

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

  1. Правила не нужны, лучшие практики не нужны, солид не нужен, разделение на компонетны не нужно, тесты не нужны, DDD не нужен, ревью не нужно, нейминг не нужен. Жгите всех, б-г узнает своих.

  2. Ой, а мне дядя менеджер время на рефакторинг не выделяет

  3. А давайте все на GO перепишем

  4. GOTO 1

Единственный, кто волен выделять или не выделять время на рефакторинг - это сам разработчик

в аутсорсе мнение разработчика самое последнее

у меня на последнем проекте было примерно так:

Вы написали что сделаете фичу за 14 дней, окей, мы согласуем вам 7 дней, релиз в пятницу, на больше бюджета нет и не просите

действительно классика: классика маразма!

никто не хочет её начинать

Так никто никогда его (рефакторинг) и не начинает.

я поняла, что его никто не рефакторил весь этот год

Я всякий раз когда смотрю в код, то понимаю, что его никто не рафакторил вообще никогда.

это очень грустная история

Для рефакторинга нужны причины, ими могут быть:

  • Рефакторинг увеличит производительность проекта;

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

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

Рефакторинг без причин - это значит задач нету и делать на проекте уже нечего.

+1. У нас (биг тех / продукт с десятизначным ревеню) рефакторинг делается перед тем как пишется фича, с конкретным обоснованием для чего. На код ревью например, если увидят трёхэтажные моки в тестах - тоже попросят отдельно отрефакторить сначала, чтобы любой джун разбуженный среди ночи понял что к чему. После того как код ушел в прод - никаких чисток чистоты ради.

Большие и сложные проекты: Требуется более частый и систематический рефакторинг

Вообще не согласен с этим поинтом. Имхо частота рефакторинга зависит от того как часто в код вносятся изменения (ведь при реализации изначального функционала оно и так должно реализовано нормально) и не сколько изначальная реализация хорошо и расширяемо написано (a.k.a. на сколько изначальный разработчик сделал решение гибким)

хорошо и расширяемо написано (a.k.a. на сколько изначальный разработчик сделал решение гибким)

существуют адепты написания кода "максимально эффективно и минималистично" когда люди целенаправленно делают нерасширяемый продукт чтобы он работал быстрее и выглядел понятнее, потому что в сиюсикундных требованиях нет запроса на расширяемость

и в таких проектах внедрение фич обычно всегда сочетается с массовым рефакторингом

я не могу однозначно сказать что это плохая практика, но тут на хабре часто звучат фразы что программисты пишут неоптимальный код ;))

"никто не рефакторил весь этот год"

ого! тут вернулся к проекту семилетней давности, и к своему глубокому удивлению, ознакомившись с кодом, я понял, что его никто не рефакторил все эти семь лет

Я вот никак не могу понять, почему на рефакторинг нужно специально выделять время, тикеты заводить, с заказчиком согласовывать... Помните, в книжке у Мартина приемы рефакторинга какие были? Переименовать переменную, выделить метод, заменить коды типами. Все быстро и не сложно, чего тут согласовывать, на что тут время выделять? Код при проведении даже довольно длинной цепочки таких рефакторингов находится в нерабочем состоянии час-два максимум, а значит, практически в любой момент рефакторинг можно прервать и вернуться к реализации фич.

Или тут под рефакторингом понимается масштабное архитектурное перепроектирование?

почему на рефакторинг нужно специально выделять время, тикеты заводить, с заказчиком согласовывать

Потому что про это спохватываются только тогда, когда единственный возможный "рефакторинг" это "выкинуть всё нахер", и в итоге всё так и остаётся как есть.

Или тут под рефакторингом понимается масштабное архитектурное перепроектирование?

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

Один рефакторинг - убрать копипасту из одного места :)

Понятное дело, что за один присест сотню-другую копипастов не убрать, в любом случае придется по одной за раз заменять. Вот одна такая замена - и есть рефакторинг. А весь процесс в целом - ну называйте, как хотите.

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

А вот если мы "развалим" код до состояния, в котором проект даже не собирается, и будем несколько дней что-то с ним делать, - ну это уже более масштабная история. Так что да, наверное, я по количеству изменений (с поправкой - одновременных изменений) отличаю одно от другого. Рефакторинг - это одно изменение за раз. Все остальное - не рефакторинг.

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

Не выйдет. Потому что копипаста, как выясняется, не совсем копипаста, а "с некоторыми нюансами". Это только в книжках всё очень просто и красиво. На деле все обстоит так, что лучше как в той поговорке про г*вно которое разумней вообще не трогать.

Понятное дело, что за один присест сотню-другую копипастов не убрать, в любом случае придется по одной за раз заменять.

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

хм, я тоже с компилируемым языком работаю (Java), и тоже многократно подобные штуки исполнял, и компилятором при этом всегда пользовался, без этого никак.

Подход в целом был таким (представим, что копипаста с нюансами):

  1. Определяем самый критичный нюанс/вид копипасты и пишем НОВЫЙ (это важно!!!) класс/метод, который в конце будет использоваться вместо этого вида копипасты. Метод ниоткуда не вызывается пока что, но уже обложен тестами, чтобы все было красиво.

  2. Призываем на помощь компилятор, чтобы отловить все места использования критичного вида копипасты. Удаляем или переименовываем класс/метод (главное, не через инструменты рефакторинга, а руками), который используется в критичной копипасте, чтобы компилятор ругнулся на все случаи такого использования. К сожалению, это не всегда возможно, точнее, результаты не всегда однозначны, могут быть и ложноположительные срабатывания, когда удаленный/переименованный метод/класс еще и вне копипасты используется.

  3. По одному месту за раз заменяем копипасту на вызов/использование нового метода/класса, каждый раз после этого прогоняем тесты.

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

Ну и понятно, что без тестов такие изменения - это уже не рефакторинг, а реХАКторинг.

PS. А если есть способ автоматически внести эти однотипные изменения - прекрасно. Но безопаснее все же руками с прогоном тестов - так скоуп изменений всегда очень ограничен и прерваться в любой момент можно.

Ну и понятно, что без тестов такие изменения

А разве кто-то пишет тесты? Разумеется, их нету. :)

  1. По одному месту за раз заменяем копипасту на вызов/использование нового метода/класса, каждый раз после этого прогоняем тесты.

Понятно что все делается последовательно по очереди, но комит то в конечном итоге у вас будет один, или 100 комитов на сто копипаст?

Изменения в конечном итоге должны меряться в комитах-мержах на мейн наверно, нет смысла считать все подряд изменения в каждой отдельной группе строчек, наверно.

комит то в конечном итоге у вас будет один, или 100 комитов на сто копипаст

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

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

Справедливости ради скажу, что за последние 4 года работы на двух проектах отдельные задачи на рефакторинг не заводились ни разу - все происходило внутри реализации фич. Прямо по заветам Кента Бека - first make the change easy, then make an easy change.

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

Там надо было параметр добавить везде где к некоторой сущности (или к их комбинации) было обращение, это обращение везде было в виде копи-паст.

Это много кода на микросервисах, он вычистил примерно 500 копи-паст

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

Я попробую переформулировать то, что пытаюсь донести.

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

у вас бы эта работа заняла пару лет, звучит не очень эффективно

Может, и все пять лет, кто знает? Если копипасты просочились туда, где ничего уже не меняется, пусть живут.

неделю чистил код

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

В общем, вопрос в цели этого процесса. Если цель - вычистить ВСЕ копипасты, ну ОК, идем чистить ВСЕ копипасты. А если цель - превратить время в деньги, тогда чистим только то, что мешает превращению.

Мы в этой ветке обсуждений уже много тем затронули. Попробую подытожить:

  1. За термином "рефакторинг" уже прочно закрепилось значение вроде "за неделю провести масштабную чистку кода" - то есть приложить значительное усилие и значительно изменить структуру.

  2. Мне, наверное, стоит (вслед за уже упомянутым Кентом Беком) перестать использовать слово "рефакторинг" для обозначения мелких структурных правок, вносимых в код на постоянной основе и требующих очень небольших затрат времени. Кент Бек начал называть это "уборкой" (tidying up).

  3. "Уборка" в целом нужна только для упрощения внесения требуемого бизнес-изменения, поэтому ее нужно проводить перед такими изменениями (и то не всегда, есть нюансы).

  4. Рефакторинг (с выделением времени, заведением тикетов и прочей бюрократией), похоже, нужен там, где на "уборку" забивают.

Sign up to leave a comment.

Articles