Флаги функций - это инженерное устройство, которое можно использовать, чтобы избежать долгоживущих веток и конфликтов при разработке продукта. Вот как это можно использовать в контексте объектно-ориентированного языка, чтобы помочь разработчикам совместно работать над определенным компонентом продукта, в то время как один обрабатывает новую версию. Это решение также может быть использовано в не объектно-ориентированных контекстах, при условии, что существует понятие «интерфейс». ( см. модульная система 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 .
Михаэль Ле Барбье Грюневальд
источник