Издержки больших проектов или взгляд на программирование в команде изнутри

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

Итак, собственно, к делу.

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

Сейчас у нас в компании около 300 программистов в 7 офисах в разных странах. Для координации разработки мы применяем Team Software Process. Но это все скучные аббревиатуры. Что же собой представляют все эти вещи для программиста?

Предположим, что принято решение разработать новую систему или проект внутри нее. Здесь хочу уточнить то, к чему мы уже привыкли, но что может быть не очевидно. У нас принято такое деление: система — это отдельный большой программный продукт, например, такой, как MS Office или Photoshop. Их у нас не так много, и новая разработка — это обычно проект по расширению возможностей одной из существующих систем.

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

Далее все идет по классическому TSP и делится на этапы.

Архитектурный анализ

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

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

После утряски всех вопросов и обновления документа пишутся требования.

Требования

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

Высокоуровневый дизайн

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

Детальный дизайн

Это самый спорный этап, который часто опускается. Для кода С++ он может быть представлен в виде include-файлов с интерфейсами классов, для базы данных — это детальное описание всех таблиц, типов колонок, индексов и т.д., для интерфейса это прототип. Т.к. такой дизайн уже мало отличается от собственно кода, то он обычно плавно перетекает в кодирование. Хотя процесс требует для него отдельной фазы.

Кодирование

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

Персональное рецензирование кода

Это не очень распространено среди разработчиков, но является довольно эффективным средством. До того, как запустить компиляцию, необходимо внимательно просмотреть собственный код. Обычно рекомендуют отвлечься на час-два после окончания кодирования, чтобы затем не предвзято взглянуть на свое творение. В свободное время можно сделать инспекцию чужого кода, пообедать и/или полазить в интернете :) Когда мы просмотрели свой код (рекомендуется скорость не быстрее 200-300 строчек в час), то можно запустить сборку. У нас часто используют компилятор для поиска банальных синтаксических ошибок еще до рецензирования, и часто это оправдано. Но процесс не рекомендует так делать. Можно с этим не согласиться, но вспомните себя, когда вы иногда в запарке по сто раз запускаете компиляцию и каждый раз исправляете 1-2 мелкие ошибки вместо того, чтобы спокойно сесть, все просмотреть, исправить и в конце запустить компилятор 1-2 раза.

Юнит-тестирование

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

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

Инспекция кода

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

Check-in

Не нашел русского аналога данного термина. Тут все понятно — код помещается в кодохранилище (CVS, SourceSafe, SVN).

Интеграционное тестирование

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

Системное тестирование

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

QA находят в системе дефекты и сообщают о них разработчикам, которые их исправляют в соответствии с назначенными приоритетами. После прохождения всех тест-планов и нескольких итеративных процедур деплоймента (после исправлений), новая или обновленная система готова для выхода в продакшен. Установкой и настройкой занимаются специальные люди — операторы. Они же осуществляют поддержку. За общение с клиентами отвечает Customer Support, но мы про них не часто слышим и напрямую почти не общаемся.

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

Инструменты

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

Кстати, исходя из личного опыта и из данных TSP, разработчик тратит в чистом виде на задачи около 18-20 часов времени в неделю (из 40). И это считается нормой. Остальное — это совещания, телефонные звонки, перерывы, другие активности. Можете проверить, если не верите.

Для хранения кода у всех разные предпочтения. Мы используем CVS. Я только скажу, что при каждом chеckin-е на специальный адрес у нас приходит письмо со всей информацией о том, что и где в коде поменялось, а так же с комментариями автора. Это бывает очень удобно при «разборе полетов», когда надо выяснить, кто когда и что испортил, а также просто для того, чтобы найти автора кода и задать ему вопрос.

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

Неудобством является то, что необходимо постоянно следить за синхронизацией упомянутых систем, т.к. сущности в них связаны (дефекты привязаны к проекту и системе, checkin-ы могут быть привязаны к дефекту и т.д.). Это неудобно, хотя частично автоматизировано. В ближайшее время планируем полностью перейти на единый инструмент – MKS Integrity (+ MKS Source как хранилище кода). Посмотрим, будет ли удобнее.

Критика

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

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

Давайте посмотрим, что можно исключить.

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

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

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

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

С кодированием все понятно.

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

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

Системное тестирование я бы делал также руками разработчиков, т.к. зачастую это быстрее, чем объяснять человеку из QA технические подробности и писать длинные тестовые инструкции. Т.е. QA может выполнять все use-cases, задуманные для пользователей, а если нужно проверить состояние базы данных или какие-то системные логи — это лучше сделает сам разработчик. Впрочем, мы так и поступаем в большинстве случаев.

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

Заключение

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

Всем желаю поменьше бюрократии и побольше интересных и творческих проектов!

Интересно!

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

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

ага, ОЕBS без разработок не бывает. Я сам разработчик под OEBS ;)

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

Здравствуй, Макс! Рад тебя видеть здесь :)
Я думаю, для нашей компании об этом можно не переживать - все равно дальше задумки дело, похоже, не идет. А так я с тобой согласен. Правда, иногда низкоуровневые фиксы легче тестировать силами разработчиков. Но на это у нас есть статус дефекта Test Pending Developer.

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

Про удобство TSP Tool — это ты преувеличил слегка. Планированию он слабо помогает, например. По крайней мере, если не следовать жесткому PSP и планировать все LOC-и на уровне классов.

Про MKS есть мнение, что лучше (намного) не будет и нужно готовиться к худшему. Хороших отзывов про эту систему в интернете не найти. Как, впрочем, и любых отзывов. Надеюсь, переживем. =)

О, а я тебя тоже сначала не узнал :) Ответил тебе в другой статье на комментарий, как незнакомому человеку :) Добро пожаловать. Вот ведь, мир тесен.

Я пришел по ссылке на статью о ценах на накопители. =)

Отлично пишете. Регулярно, с удовольствием читаю Ваши материалы.

Спасибо за поддержку :)

Захар, интересная статья. А что скажете по вопросу основания своей команды, человек из 3 хотя бы. Меня больше волнует организационный и вопрос психологии. Как изначально выстроить отношения в команде? Или как не заставить, а мягко подтолкнуть своих коллег по опасному бизнесу))) в нужном направлении и к нужным отношениям. Все ж эгоисты, а работать в команде - стимул нужен. чтобы поступиться своими интересами... Вот такие вот вопросы у меня. Для меня совсем непростые.

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

Наибольшее впечатление на меня произвела книга Тома ДеМарко "Deadline". Поищите - она есть в свободном доступе. Это очень полезная книга, на многое открывает глаза. Ну и согласен с Вами, что это реально сложно, одними книгами не обойтись. Нужна своя голова и анализ конкретной ситуации :)

Спасибо, обязательно почитаю. А можно вопрос? Зачем CQG набирать программистов в разных городах? Например, в Тольятти, в этой глухомани, идет поиск персонала. Предлагают, кстати, что то около 30000 рублей.

Насчет Тольяти - я думаю, что это набор для самарского офиса. У нас разработка в Москве, Зеленограде, Киеве, Самаре и Ереване (ну еще в Денвере головной офис). А причина открытия региональных офисов была, я думаю, в стремлении к удешевлению разработки и в том, что в Москве сейчас дефицит хороших программистов.

Я как то хотел к вам устраиваться, но переезд меня смутил. Нет вариантов удаленной работы? Мечта программиста....(

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

Отправить комментарий

КАПЧА
Пожалуйста, введите капчу (здесь ТОЛЬКО буквы!)
CAPTCHA на основе изображений
Enter the characters (without spaces) shown in the image.