Ответы:
Флаги функций - это инженерное устройство, которое можно использовать, чтобы избежать долгоживущих веток и конфликтов при разработке продукта. Вот как это можно использовать в контексте объектно-ориентированного языка, чтобы помочь разработчикам совместно работать над определенным компонентом продукта, в то время как один обрабатывает новую версию. Это решение также может быть использовано в не объектно-ориентированных контекстах, при условии, что существует понятие «интерфейс». ( см. модульная система OCaml.)
Для иллюстрации мы предполагаем, что инструмент представляет отчеты о данных, хранящихся в базе данных. Код реализует класс DatabaseClient, используемый для выполнения запросов. По мере роста набора данных становится ясно, что некоторая альтернативная компоновка данных может повысить производительность приложения. Поэтому Алиса разработает новую версию DatabaseClient, способную извлекать данные из структур с улучшенной компоновкой, а Боб будет поддерживать исторический DatabaseClient .
С помощью следующих шагов Алиса и Боб могут сотрудничать на коротких ветвях, сводя к минимуму их конфликты.
Алиса переименовывает DatabaseClient в DatabaseClient_v1 и создает класс делегата DatabaseClient, который использует объект DatabaseClient_v1 и реализует интерфейс DatabaseClientInterface. (Если возможно, этот DatabaseClientInterface должен быть артефактом кода, но языки типа «утка» не всегда поддерживают это.)
Боб просматривает изменения, сделанные Алисой в 1 и знает, что его работа по обслуживанию должна происходить в DatabaseClient_v1 .
Алиса вводит новый флаг конфигурации в приложение, которое управляет поведением делегата DatabaseClient и реализует заполнитель DatabaseClient_v2 , класс, реализующий DatabaseClientInterface , все методы которого генерируют исключение «Не реализовано».
После этого Алиса и Боб могут сотрудничать без явной синхронизации, поскольку код, написанный на их соответствующих итерациях, является объектом DatabaseClientInterface . Это сводит к минимуму риск конфликта в результате их параллельной работы.
Итерации от Алисы могут быть очень короткими, такими как выполнение теста, реализация метода или даже частичное выполнение, потому что в производственном процессе код не выбран для использования и не должен быть полностью функциональным. Автоматический набор тестов должен быть настроен таким образом, чтобы DatabaseClientInterface всегда использовал DatabaseClient_v1, в то время как Алиса может легко переключаться на DatabaseClient_v2 при локальном запуске testsuite или в пользовательской настройке CI. Как только все будет готово, одно изменение может выполнить изменение, обновив значение конфигурации, управляющее делегатом DatabaseClient .
Шаги довольно «легки», чтобы перейти к приложению с признаком функции, вам понадобятся две вещи:
Основной флаг функции - это их включение / выключение, но вы быстро захотите выпустить новую функцию в ускоренном режиме, например: 1 сервер на 5, на котором размещено приложение, имеет функцию «вкл» для запуска, Затем вы включаете функцию на другом сервере, пока она не будет включена на всех серверах.
Это означает, что вы должны быть осторожны, чтобы ваша функция была совместима с приложением без него (например, дополнительный столбец в БД).
Фреймворки существуют на разных языках, чтобы не изобретать велосипед, у теперь не поддерживаемого Etsy есть интересный файл readme, чтобы объяснить, как он работает.
Мир встроенного программного обеспечения часто использует флаги времени сборки, в самом коде приложения ( например, в операторах #define
/ #ifdef
) и / или в файлах конфигурации инструментов сборки ( makefile
например, в).
Аналогичным образом можно использовать флаги сборки не только для функций, но и для всех видов рефакторинга кода, миграций, поддержки отладки и т. Д.). Они позволяют вносить в ветку интеграции частичные или непроверенные изменения, не нарушая сборку и не вызывая регрессии в функциях / проектах, уже работающих в ветке. Отлично подходит для обработки точечных исправлений наряду с большими / рискованными / медленными изменениями прогресса (которые в противном случае потребовали бы долгоживущей ветви) в режиме непрерывной интеграции.
Но в дополнение к проверке уже существующего кода ветвления для регрессий, также можно выполнить проверки прогресса / стабильности нового кода. Для этого необходимо изменить флаги времени сборки.
Один из способов переключения флагов заключается в использовании в отдельном конвейере проверки системы CI той же ветви (если он поддерживает такую функциональность) патч-файла, переключающего флаг - для применения к отдельному рабочему пространству до строить. В этом рабочем пространстве будет создан другой набор артефактов, а затем проверен.
В качестве альтернативы долгоживущую ветвь функции можно извлечь из основной ветви интеграции, но единственным изменением в этой ветви функции будет флаг переключения. Благодаря этому крошечному изменению ветвь функций может автоматически очень быстро синхронизироваться - практически очень близко скрывая основную ветвь интеграции. Отдельное выполнение CI в этой ветке больше не будет нуждаться в предварительном патч-файле. Было бы несложно носить такую ветвь функций даже в течение длительного периода времени.
Также возможно создать в основной ветви интеграции новые артефакты сборки, которые на самом деле будут просто клонами существующих артефактов сборки, но с переключенными флагами. Таким образом, ни предварительный файл патча, ни ветвь возможностей не потребуются для проверки нового кода прямо в основной ветке.