Большинство идей в этом документе известны опытным разработчикам. ПРИНЦИПЫ УПРАВЛЕНИЯ Есть множество моделей управления разработкой, из которых сейчас возобладали разные вариации Agile. Причем эта методология приобрела статус догмы и ожидаемо породила секты фанатиков. Мы не следуем какой-либо готовой модели и используем свою, беря наилучшее из разных подходов. При этом всячески остерегаемся догматизма, соблазна "забронзоветь". Из Agile мы берем гибкость. Это значит что мы меняем любые мешающие правила. Итеративность и связанные с нею ритуалы не нужны, из-за специфики потребителей нашего софта. Мы сохраняем отсутствие иерархичности в анархической самоорганизации: - прямое общение каждого с каждым по любому вопросу - прямое общение разработчика с заказчиком - сетевую организацию рабочих групп - множество ролей у участника в зависимости от вовлеченности в тот или иной проект (тех.лид в проекте А, исполнитель в проекте Б, заказчик в проекте В) Из методик разработки свободного ПО мы берем систему контроля версий и систему учета ошибок. Эти системы стали широко применяться именно в начале 90-х в рамках разработки проекта Mozilla и другого свободного ПО, хотя почему-то считаются атрибутами Agile. От бюрократии проектной разработки мы берем историчность, возможность найти то, что уже когда-то было. Помним: ЖИЗНЬ является самоорганизацией хаотической материи. Хаосу свойственна самоорганизация на потоках энергии. Мы и есть этот ХАОС. ЖИЗНЬ сама нас поправит, когда мы начнем коснеть (а вовсе не некие волшебные методики). ПРИНЦИПЫ КОДИРОВАНИЯ * В стиле кодирования основное - это имена. А вовсе не скобочки и отступы. Умение давать имя, именовать - это показатель уровня разработчика. Если вы дали хорошее и подходящее имя переменной или функции или классу, то все остальное почти автоматически будет хорошо. Если наоборот - то почти автоматически все остальное будет плохо. Хорошее имя - это не значит длинное. Это значит уместное, подходящее, меткое, точно отражающее суть, наилучшим образом характеризующее, грамматически правильное, используемое и узнаваемое другими в похожем контексте. Возможно вы замечали, что в подменю Visual Studio "Рефакторинг" пункт "Переименовать" стоит первым. Неверный выбор прорастет в коде навеки! Бойтесь опечаток наподобие imfo или autometic - ошибаетесь один раз и навсегда. Хуже всего, если такой идентификатор с опечаткой попадет в интерфейс!!! Если у вас код разнесен по нескольким подсистемам на разных языках программирования и интерфейсах, используйте одно и то же имя везде. Трудно искать несоответствия, когда на С++ переменная звучит как errno, в HTTP API передается как errLvl, а в логах выписывается как errorLevel. * Комментарии объясняют то, что не объясняют хорошо выбранные имена. У нас много магии используется. Объясняйте _намерения_ кроме _методов_, по максимуму, развернутыми комментами. Надо писать не только "что и как я делаю", а в первую очередь "зачем я делаю, какую цель достигаю, какую проблему решаю". плохо // аллоцируем память в удаленном процессе и запускаем шелл-код хорошо // нам нужно снять хуки на такую-то функцию в удаленном процессе, потому что иначе не заработает то и это // поэтому аллоцируем память в удаленном процессе и запускаем шелл-код, который взят вот отсюда с гитхаба https://... // шелл-код отыщет такие-то байты в прологе такой-то функции и пропатчит их на нужные нам. // были еще варианты раз (ссылка) и два (ссылка), но они не подходят, т.к. плохо отрабатывают на таких-то системах В компилируемых языках программирования (далее ЯП) комментарии пишутся на русском языке. В интерпретируемых ЯП комментарии и идентификаторы только на английском, только грамматически чисто! Попавшие противнику скрипты не должны указывать на вашу национальную принадлежность. * Лучший код тот, которого нет. Не пишите лишнего. Не делайте заделы на годы вперед. "Завтра" может не настать, и задел никому не понадобится. "завтра" окажется, что вы не угадали. Лаконичность, минимализм - наше все. Не плодите сущностей. Это величайший грех инженера! Отсеките Бритвой Оккама все лишнее - фреймворки, ООП, сторонние библиотеки, обертки. Идеальный код должен занимать ноль байт (это реальный случай, когда используется чужой софт). * нет смысла писать код, если он кем-то уже написан. Перед тем как писать, поищите в Сети. Если взяли чужой код, обязательно воткните в исходники линк, откуда он взят. ОБРАБОТКА ОШИБОК Предлагается следующая методика обработки ошибок в коде: - исключения С++ не используются - исключения SEH/VEH используются только для снятия посмертного стека либо для защиты опасных секций кода (например, выполнение произвольного shell-кода) - все функции пишут об ошибке немедленно в stderr, предваряя строку именем функции. Например: fprintf(stderr, __FUNCTION__ " Invalid file handle\r\n"); - если функция возвращает коллекцию (например, найденных символов), то в случае ошибки возврат - пустая коллекция; - если функция возвращает указатель, то NULL - это ошибка; - если функция возвращает строку, то пустая строка - это ошибка; - если функция возвращает целое, то 0 или -1 - это ошибка; Вызывающий контекст проверяет возврат, и если он неожиданный, и нету возможности подставить значение по умолчанию, мы делаем возврат из текущего места по приведенным выше правилам сигнализации об ошибках. ПОЛИТИКА GIT * Мы используем Git не потому что так делают все, а для решения вот таких задач: 1. Резервное копирование. Мы видели множество случаев потери работы за длительное время (месяцы, и однажды - год), просто из-за неаккуратности разработчика. 2. Совместная работа нескольких людей над проектом 3. Поиск автора конкретных строк кода 4. Поиск регресса путем отката и последовательных сборок по истории 5. Ведение истории изменений (Release notes, Changelog) 6. Версионирование, управление релизами Поэтому правила ниже и написаны для извлечения этих выгод. Для других задач могут быть другие правила. * Коммиты обязательны всякий раз, когда есть что коммитить (то есть примерно каждый день). Даже если код не работает и не дописан, коммитьте во временную ветку. Это лучше чем потерять работу за день. * Желательно хранить стабильный код в отдельной ветке, и вливать в нее только проверенные изменения. * Если у проекта есть версии, то каждой версии соответствует либо ветка (если она передается на поддержку), либо метка (если нужна лишь историчность без поддержки). * Если вы на проекте один, то вы ведете ветки как вам угодно. * Если проектом заняты несколько, то разработку следует вести в личной ветке. Влитие в основную ветку всегда делается двойным слиянием (merge) - сначала из основной ветки в свою (с разрешением конфликтов и дымным тестом) - потом из своей в основную. * У коммита всегда должен быть комментарий, на русском языке, описывающий краткую суть изменений. Например: "Исправление переполнения сетевого буфера при высокой частоте запросов". В комментарии должен быть указан номер бага или задачи из системы учета, например: "B-1655 Исправление переполнения сетевого буфера при высокой частоте запросов". Когда вы проставите ИД бага, интеграция Git с системой учета ошибок автоматически свяжет коммит с багом. * Коммит должен быть атомарным и минимальным. Один коммит - один баг/задача. Это значит, что больше нельзя фигакнуть git push не разбираясь прямо из каталога проекта. Если вы из командной строки, то нужно перечислять файлы поименно, и перед коммитом обязательно делать diff с апстримом. Коммитятся только те файлы, которые имеют отношение к одной-единственной задаче. Коммитятся только те строки файла, которые имеют отношение к одной-единственной задаче. Если не следовать этому правилу, становятся недоступными или затрудненными следующие выгоды Git: - cherry pick (перенос кода между несинхронными ветками) - blame (поиск автора кода) становится очень зашумленным - поиск регресса путем последовательных сборок по истории (при возникновении ошибки в таком коммите, невозможно сказать, к изменению по какой задаче она относится) * Используйте утилиты с UI для работы с Git. Они показывают что именно изменено относительно основной ветки, позволяют отправлять только отдельные строки из файла, и игнорировать ваши личные отладочные изменения и настройки, которые не должны попасть на сервер. * Запрещено коммитить - любые тексты с реальными именами, никнеймами, паролями, URL и IP-адресами наших ресурсов, адресами криптовалют, итд итп (если не оговорено особо) - архивы и бинарные файлы, не являющиеся частью шагов сборки проекта СИСТЕМА УЧЕТА ОШИБОК И ПРОЕКТНОЙ РАЗРАБОТКИ Этой системой мы пользуемся не потому, что ими пользуются все, а для решения вот каких задач: 1. Чтобы сократить писанину. Можно ткнуть в уже написанный текст, а не писать кому-то повторно. Это может быть текст задачи, комментарий с описанием шагов воспроизведения ошибки, картинка или лог во вложении. 2. Чтобы найти концы (историчность). Ошибки могут повторяться, особенно плавающие. Большое число ошибок группируется вокруг одних и тех же строк кода. Словом, ситуация "такое уже было" является частой. 3. Для концентрации знаний и аналитики. Через какое-то время в системе накапливается существенное количество информации. Куда идти разработчику или руководителю за информацией, как не в эту систему? 4. Для управления разработкой. Ведение списка задач, назначение задач исполнителям, выбор приоритетов, отслеживание стадии работ, планирование. Коллеги разработчики, когда вас сотня, а я один (ну ладно, двое или трое), держать в голове это все очень тяжко. Багтрекер кроме всего прочего является вашим рабочим журналом. При работе над задачей, записывать заметки для самого себя - это нормально. Когда что-то получается, или наоборот что-то не получается - записи вида "не получилось это, вот формулировка проблемы" - очень ценны. ПРАВИЛА ОФОРМЛЕНИЯ ОТЧЕТОВ ОБ ОШИБКАХ См.соответствующий документ.