LINUX.ORG.RU

[berserk mode] как отрефакторить 40к строк легаси-кода?


0

1

Работаю над проектом, perl/bash/java. Проект представляет собой дикую мешанину скриптов плюс функциональные тесты на джаве (гусары, молчать).
После очередного проведенного на работе воскресенья по причине того, что сроки давно сгорели, а фича, с виду элементарная, так и не сделана, решил, что так жить больше нельзя. Хочу запилить глобальный рефакторинг с целью упрощения читаемости и поддерживаемости кода. Потому что смотреть на самодельные костыли, которые воткнуты даже вместо модулей из Perl Core (File, Cwd, Carp и т.д.) сил уже нет. Собственно вопрос - как сделать, затратив минимум времени (сильно сомневаюсь, что его кто-то оплатит, либо придется долго и упорно доказывать необходимость такого шага) и получив максимум профита? Писать сначала юнит-тесты? Или функциональных будет достаточно чтобы убедиться, что регрессии не внесли? Реквестирую маны, напутствия, советы бывалых, истории успеха. Уволиться не предлагать, 25 дней из 30 тут все хорошо и тихо, не мешает учебе, а платят - я столько не выпью

Хочу запилить глобальный рефакторинг

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

baverman ★★★
()

вспомнилось.

// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 16


)

по теме: бить на кусочки, тут же допиливать тесты.

kelyar ★★★★★
()
Ответ на: комментарий от baverman

лол, откуда инфа про 40к? Это девелоперу столько платят? Пусть тогда ТС идёт в суппорт: там хоть тыщ 60 платят.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

По САБЖу: лучше убедить начальство, что рефакторинг необходим. Привести обоснования. Например то, сколько времени у тебя занимает имплементация такой-то фичи и сколько процентов из этого занимает разбирательство в этой вермишели. При этом надо заранее оценить сроки на рефакторинг и их озвучить.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

По САБЖу: лучше убедить начальство, что рефакторинг необходим. Привести обоснования. Например то, сколько времени у тебя занимает имплементация такой-то фичи и сколько процентов из этого занимает разбирательство в этой вермишели.

так и хочу попытаться сделать

marvin_yorke ★★★
() автор топика
Ответ на: комментарий от DELIRIUM

К вопросу о деньгах, это в ДС 40к - мало, у нас это существенно выше среднего. А у меня 30к сейчас, при том что я работаю полтора года, да еще и на учебу бегаю временами

marvin_yorke ★★★
() автор топика
Ответ на: комментарий от baverman

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

marvin_yorke ★★★
() автор топика

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

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

kulti ★★
()

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

nanoolinux ★★★★
()
Ответ на: комментарий от kulti

Рефакторинг без тестов - медленное самоубийство. Я уже пару раз в продакшне накосячил (замечено было не сразу), теперь сначала тесты, и только потом - рефакторинг. И хрен с ним, что до первого теста иногда проходит 3 дня.

JackyTreehorn
()

ps Для аргументации в сторону начальства еще можно взять статистику (о стоимости багов на различных этапах разработки и тестирования) из, кажется, «Code complete».

JackyTreehorn
()
Ответ на: комментарий от JackyTreehorn

Да, тут я с вами согласен. Но когда логика и UI - это один сплошной клубок? Как обкладывать развесистый UI тестами? Я пока ничего вменяемого не встретил, к сожалению...

kulti ★★
()
Ответ на: комментарий от kulti

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

Для начала рекомендую уже упомянутого Физерса. Если у тебя с++ и интересует мой опыт - можно по мылу.

JackyTreehorn
()
Ответ на: комментарий от JackyTreehorn

Чужой опыт - это всегда интересно. Мне пока не приходилось легаси код обкладывать тестами, но думаю Физерс тут как раз и поможет, если есть, что добавить, подсказать, чтоб на те же грабли мне не наступать - пиши гугло-почту kultihell.

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

Пишу на С++, для тестов - GoogleTest

kulti ★★
()

Чувак, кроме книг по программированию ещё не мешало бы почитать книги по управлению(людьми). Владимира Тарасова например(ректор Талинской школы управления). И ещё трудовое законодательство почитай.

PS Работать по воскресеньям. Да он псих =:-/

andreykyz ★★
()
Ответ на: комментарий от andreykyz

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

marvin_yorke ★★★
() автор топика
Ответ на: комментарий от marvin_yorke

marvin_yorke

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

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

marvin_yorke

Но нервов потратил бы еще больше.

Тренируйся относиться проще, тебя никто не гонит. Если у твоего начальника нет ничего кроме работы это его проблемы. Например у меня есть семья и когда меня ген. дир. позвал на совещание я попросил его перенести на среду т.к. сем обст. и все было ок. Хотя основная серая масса планктона повиновалась. Или ты думаешь что на твое место уже ждут ещё большего трудоголика? Расстаться с человеком для работодателя сложнее чем кажется и дело далеко не в законах.

andreykyz ★★
()
16 июля 2012 г.

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

Тесты пишутся до: все скрипты компилятся, тест зависимостей (CPAN и соседние проекты), список функций для каждого модуля, защитное программирование - гуарды на входе (и выходе - и такое бывает) каждой функции.

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

outtaspace ★★★
()

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

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

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

outtaspace ★★★
()

40к

Комиссара на тебя нет.

anonymous
()

После очередного проведенного на работе воскресенья

Жесть.

Да, разбей на функциональные модули и переписывай их по отдельности. Вместе с тестами.

А уже потом рефакторинг (изменение внешних интерфейсов этих модулей).

unfo ★★★★★
()
Ответ на: комментарий от marvin_yorke

проверка данных, на входе функции и выходе, наверное

Virtuos86 ★★★★★
()
Ответ на: комментарий от marvin_yorke

Я покажу на примере.

use Test::More;
use Test::Exception;

# конструктор new() принимает именованные параметры:
# параметр dbh - обязателен
throws_ok { $MODULE->new(); }
    qr{^key\s'dbh'\svalidation\serror:\sparameter\smust\sbe\srequired}xms,
    'конструктор new() принимает обязательный именованный параметр "dbh"';

А в теле класса, в конструкторе, стоит гуард, в декларативном стиле описывающий что пришло и падающий при любом несовпадении требуемого с действительным:

use JIP::CheckParams qw( check_named_params );

sub new {
    my ( $self, %param ) = @_;

    # именованный параметр (всегда стараюсь такие использовать) "dbh" - датабейсхэндл
    # обязателен, всегда defined, инстанс класса DBI::db
    # все это проверяется в юнит-тестах
    check_named_params(
        rules_ref  => {
            dbh => { required => 1, defined => 1, isa => 'DBI::db' },
        },
        params_ref => %param,
    );

    # далее код инстанцирующий класс
}
outtaspace ★★★
()

Слегка ошибся когда правил копипасту. Передается ссылка на хэш:

check_named_params(
    rules_ref  => {
        dbh => { required => 1, defined => 1, isa => 'DBI::db' },
    },
    params_ref => \%param,
);

outtaspace ★★★
()
Ответ на: комментарий от outtaspace

ого, спасибо, давно не помню таких внятных и развернутых ответов на ЛОРе

marvin_yorke ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.