Разработка при ограниченном человекоресурсе.
От: Maxim S. Shatskih Россия  
Дата: 22.11.07 16:29
Оценка: 31 (5)
Предлагаю обсудить эту тему. Выскажу свои соображения, с четким осознанием, что они могут оказаться неверными

Первое и главное. ( Сроки * качество * функционал ) = ( const * человекоресурсы ). То есть — надо сразу выбрать, чем жертвуем — сроками, качеством или функционалом.

Ситуацию, когда в жертву приносится качество, я обсуждать просто не готов. Нулевой практический опыт в этом. Разумные вещи ИМХО на эту тему сказал Гапертон в теме "совет от мудрого человека".

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

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

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

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

Это особый вид лени. В нем "за борт" отправляется не то, что требует напряжения или что неприятно, а осознанно то, что требует человеко-часов.

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

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

Очень осторожно надо относиться к test-driven методологическим паттернам. Для оценки того, можно ли в данном месте применять test-driven, предлагается использовать воображаемую метрику "примерная цена поиска бага в человеко-часах". Если баг в каком-то месте кода _неизбежно сразу бросится в глаза при почти любом сценарии использования_ — то и не нужно там никаких юнит-тестов. Юнит-тесты крайне нужны для тех компонент, баг в которых очевидно будет тяжел в поиске, например, может "отзвонить" в совсем другое место в системе, или сильно зависит от входных данных, или что-то вроде.

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

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

Обвешивать все вообще юнит-тестами — это такое же безумие, как ехать 60км/ч в левом ряду фривея. При том, что на очень многих улицах и дорогах 60км/ч таки превышать не стоит. Что же касается сочетания test-driven и "разработки начерно", известного под названием "XP" — то это сочетание езды 60км/ч (даже на фривее) с полным отсутствием контроля давления в колесах, из соображений — "если и спустило, то не убьюсь". Сочетание ИМХО близко к безумию.

За борт идут все соображения ортогональности вида "если написали operator+, напишите и operator-". Нет. Не так. Сначала плюс. Потом — когда минус будет нужен при реализации какой-то фичи — вот тогда напишем минус.

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

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

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

Главный критерий стиля кодирования — понятность. Никаких головоломок в коде. Лучше — локальная понятность, т.е. избегать оборачивания чего-то в классы, чтобы потом компилятор Си++ все сделал сам, развернув деструкторы и operator+. Лучше явно все написать.

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

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

Если же такое все же произошло — то рефакторинг можно оставить "на потом". "Здесь и сейчас" надо реализовывать фичи. Рефакторинг — когда время будет. Лучше спагетти, чем затягивание сроков.

После рефакторинга (может быть совмещено с реализацией очередной фичи) — тут же оттестировать затронутый кусок, желательно все кейсы.

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

Осторожнее с джуниорами. Ввод джуниора в курс дела и его обучение — опять же сроки.

Меньше митингов. Это колоссальная затрата времени нескольких человек. Единственное разумное зерно в митинге — сделать так, чтобы все понимали задачу одинаково. Только это. Использование митингов для сбора статуса — зло. Статус-репортинг — штука индивидуальная.

Ну вот примерно так.
Занимайтесь LoveCraftом, а не WarCraftом!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.