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

Проблема


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

  • Создать отдельную ветку и в течение трёх месяцев выполнять в ней всю работу, периодически делая pull из родительской ветки
  • Использовать концепт непрерывной интеграции (Continious Integration или коротко CI): декомпозировать задачу и мёржить код небольшими порциями

Оба этих подхода имеют свои вполне очевидные достоинства и недостатки:

Достоинства Недостатки
Долгоживущая ветка Код вашей неготовой фичи не будет находиться в родительской ветке и не будет мозолить глаза другим разработчикам
  • Постоянные merge-конфликты, которые вам потребуется разрешать
  • Монструозный pull request, непригодный для code-review

Много коммитов из веток, с коротким сроком жизни Задача хорошо декомпозирована и мёржится небольшими порциями, нет необходимости разрешать merge-конфликты Ваша неготовая фича будет нервировать других разработчиков и, возможно, вызывать сторонние эффекты на UI

Использование feature switcher-ов для решения проблем


Такая проблема встречается в разработке довольно часто и есть изящное решение, позволяющее взять лучшее от описанных выше подходов — feature toggle или feature switcher.

По сути, feature switcher — это boolean флаг, который хранится в базе данных и содержит информацию о том, должна быть включена та или иная фича или нет. Значение этого флага может быть извлечено из базы данных по ключу. Удобство использования feature switcher-ов заключается в том, что они могут быть легко изменены бизнес-пользователем во время runtime через панель администратора без необходимости заново деплоить приложение.

Ниже приведен пример использования feature toggle на языке Java:

if (configurationManager.getParameter("is.some.functionality.enabled")) {
    // do some stuff
} else {
    // do default logic
}

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

Также, при помощи feature switcher-ов, можно отображать/скрывать определенные элементы на фронтенде. Для этого придется положить значение флага в Model и передать его на View как это показано ниже:

@ModelAttribute("isSomeFunctionalityEnabled")
public void isSomeFunctionalityEnabled() {
    return configurationManager.getParameter("is.some.functionality.enabled");
}

После чего использовать переданное значение для рендеринга того или иного HTML кода:

<c:choose>
  <c:when test="${isSomeFunctionalityEnabled}">
    <!-- Render some stuff -->
  </c:when>    
  <c:otherwise>
    <!-- Render some other stuff -->
  </c:otherwise>
</c:choose>

Виды feature switcher-ов


Описанный концепт использования feature switcher-ов — это лишь один возможный случай использования и такие feature switcher-ы называются release toggles. Всего выделяют 3 разных вида feature switcher-ов:

  • release toggles — позволяют скрывать не до конца имплементированные фичи во время их разработки
  • experiment toggles — переключатели для A/B-тестирования
  • permissioning toggles — включатели/выключатели фич для различных групп пользователей

Таким образом, используя feature switcher-ы, можно построить две различные версии сайта на одной кодовой базе, используя разные БД и разные наборы feature switcher-ов. Например, на европейском сайте имеет смысл включать все фичи, имеющие отношение к GDPR, а на российском этого можно и не делать.



Проблемы использования feature toggle-ов


Поскольку я работаю на проекте, где активно используются feature toggle-ы, то кроме очевидных достоинств их использования я начал замечать и проблемы, связанные с ними:

  • Сложность тестирования: при выходе нового релиза, QA инженеры тестируют все фичи, которые в него входят, а также пробуют включать и выключать их, используя feature switcher-ы. Это требует большого количества дополнительного времени, так как желательно протестировать всевозможные комбинации флагов
  • Появление мёртвого кода: значения многих feature toggle-ов не меняются на протяжении длительных промежутков времени или не меняются вовсе, и таким образом код, написанный для другого значения флага, фактически становится «мёртвым»
  • Неожиданные поломки сайта: многие из устаревших feature switcher-ов имеют досадное свойство ломать что-либо при изменении своего значения (так как никто давно не проверял, что они работают). Так как feature switcher-ы хранятся в БД и могут быть легко изменены бизнес-пользователями из панели администратора, часто происходят поломки, вызванные изменением их значения. Работоспособность давно неиспользованных feature switcher-ов стоит сперва проверить на тестовом окружении

Решения некоторых из описанных проблем


Помочь решить вышеописанные проблемы могут следующие действия:

  • Документирование имеющихся feature switcher-ов: чтобы понимать, какой эффект имеет тот или иной feature toggle и по какому ключу его искать в базе данных, следует создать подробную документацию с описанием всех feature switcher-ов.
  • Периодическая ревизия feature switcher-ов: чтобы избежать появления “мёртвого” кода, нужно периодически удалять устаревшие feature switcher-ы и связанный с ними код

Итоги


Feature switcher — очень простой и одновременно мощный механизм, позволяющий избегать монструозных коммитов, легко менять поведения приложения или собирать несколько разных приложений на одной кодовой базе, используя разную конфигурацию feature toggle-ов.

Однако, стоит также помнить, что этот паттерн разработки имеет некоторые недостатки, которые выливаются в трудночитаемый и трудно поддерживаемый код, поэтому следует избегать чрезмерного использования этого паттерна и периодически проводить документирование feature switcher-ов и их ревизию, чтобы удалять неиспользуемые и, как следствие, очищать проект от “мёртвого” кода.

Полезные ссылки


Комментарии (62)


  1. kinall
    17.08.2019 18:23

    То есть когда я юности писал что-то вроде

    if ($_SERVER['REMOTE_ADDR'] != '127.0.0.1')
    error_reporting(E_ALL ~E_WARNING)
    

    , это я, оказывается, feature toggle делал. Буду знать=)


  1. VladVR
    17.08.2019 18:57

    Фича тогглы это такое жуткое зло, лучше уж мерж. Они превращают проблему одного человека в проблему всей команды. При мало-мальски недисциплинированных разработчиках проект все время в «красном» состоянии. Зачастую он даже не компилируется. И CI работает лишь как индикатор — появился коммит, загорелся сигнал, что мастер сломан. Где то тут на хабре даже кто то уличный светофор приволок в офис, чтобы этот сломанный мастер сразу было видно. Очевидно, ломается он нередко. И надо об этом быстро узнать и подорваться и чинить. И разработчики все время стараются свалить на кого то вину. «Это он своим коммитом меня сломал, у меня все работало!!!»

    С большими мержами надо бороться другими способами. Во первых код должен быть хорошо декомпозирован. При этом два разработчика работающие над двумя разными фичами не будут пересекаться, собственно потому что фичи декомпозированы друг от друга. Нет пересечений — нет мержей. Кроме этого чисто математически — чем больше файлов, тем меньше вероятность пересечься в одном файле. Во вторых фичи должны быть маленькие. Руби коммьюнити для нас всех придумали отличный инструмент для этого. Надо заставить аналитика писать gherkin тесты, и один тест — одна фича, а не как ему «на берегу» кажется, 100500 фич, вроде бы друг к другу относятся, тем более одни от других зависят, дай ка я их оформлю в одну историю. Фичи, которые быстро разрабатываются, очевидно, исключают долгоживущие ветки.
    И в случае веток, CI это не индикатор, это защитник. Он не дает вмержить «красную» ветку, поэтому мастер всегда зеленый. Нерадивый разработчик не может даже теоретически свалить вину на кого то. Если твоя ветка красная — виноват, очевидно, только ты.


    1. lair
      17.08.2019 19:10

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

      А как "проект все время красный" вытекает из feature toggles? По-моему так ровно наоборот.


      При этом два разработчика работающие над двумя разными фичами не будут пересекаться, собственно потому что фичи декомпозированы друг от друга.

      Это пока у вас фичи ядро не затрагивают.


      Кроме этого чисто математически — чем больше файлов, тем меньше вероятность пересечься в одном файле.

      Проблемы мержа возникают не только тогда, когда правки в одном файле.


      Надо заставить аналитика писать gherkin тесты, и один тест — одна фича

      А что такое "один тест"? Он покрывает и положительные, и отрицательные сценарии?


      а не как ему «на берегу» кажется, 100500 фич, вроде бы друг к другу относятся, тем более одни от других зависят, дай ка я их оформлю в одну историю.

      Есть такой нюанс: иногда есть фичи, которые по отдельности маленькие, но выпускать (т.е., показывать пользователю) можно только вместе. И да, вмерживать их надо (и можно) по отдельности, а вот чтобы пользователь их не видел, помогают… внезапно, feature toggles.


      1. VladVR
        17.08.2019 22:51
        -1

        А как «проект все время красный» вытекает из feature toggles? По-моему так ровно наоборот.
        Анекдот такой был — в пьянстве замечен не был, но по утрам жадно пил холодную воду. Для одних светофор в офисе дает сигнал, что мастер надо чинить, для меня он дает сигнал, что фича тогглы — зло.

        По факту вытекает. Вижу проект с фича тогглами и периодически слышу, что мастер опять не собирается.


        1. lair
          17.08.2019 22:54

          Для одних светофор в офисе дает сигнал, что мастер надо чинить, для меня он дает сигнал, что фича тогглы — зло.

          Вы, наверное, и на улице такие же выводы делаете? Раз уж светофор красный?


          Вижу проект с фича тогглами и периодически слышу, что мастер опять не собирается.

          А я вот вижу проект без feature toggles, и все равно периодически слышу, что мастер не собирается. Так что же зло тогда?


          1. asolntsev
            21.08.2019 10:30

            Думаю, имелось в виду, что зло не фича тогглы, а процесс, когда все подряд коммитят в мастер. А вот когда все коммитят в разные ветки, то они ломают только свои ветки. А в мастер мержат только зелёные ветки, поэтому мастер, как правило, зелёный.


            1. lair
              21.08.2019 11:02

              Когда дважды прямым текстом написано "Фича тогглы это такое жуткое зло" — сложно догадаться, что имеется в виду что-то другое.


    1. VolCh
      17.08.2019 21:27

      Нет мерже-конфликтов не значит нет пересечений. Банально добавили абстрактный метод, добавили имплементации в наследников, но тут в другой ветке добавили нового наследника.


      1. VladVR
        17.08.2019 22:52

        И это как раз тот случай, когда в проекте с фича тогглами «опять упал мастер», а в случае с ветками все хорошо.


        1. lair
          17.08.2019 22:55

          Неа. Мастер упал в обоих случаях, просто в одном (с feature toggles) — рано (что хорошо), а в другом (без них) — поздно (что плохо).


          1. VladVR
            17.08.2019 23:28

            Я наверное просто так написал, что CI служит барьером, и красный коммит в мастер никогда не попадает в принципе.
            Ну либо кто то не знает о существовании галочки запрещать мержить в мастер коммиты которые не фаст-форвардятся из него.
            Ах да, только что ты говорил, что мастер не падает с фича тогглами, теперь таки согласен, что падает, прогресс, поздравляю.


            1. lair
              17.08.2019 23:31

              Я наверное просто так написал, что CI служит барьером, и красный коммит в мастер никогда не попадает в принципе.

              Ну так это от feature toggle никак не зависит, либо есть такой барьер, либо нет.


              Ах да, только что ты говорил, что мастер не падает с фича тогглами

              Где?


            1. VolCh
              17.08.2019 23:59

              Фаст-форвард тут совсем не причём. Хоть с ним, хоть без него может оказаться в мастере наследник без реализации только что появившегося абстрактного метода.


              1. VladVR
                18.08.2019 00:30

                Не может. Пулл реквест нельзя вмержить, если CI повесил на него красный результат. Также его нельзя вмержить если при мерже создастся мерж-коммит.
                Это две галочки в настройках.

                ЗЫ К слову, этот пример еще и есть нарушение принципа Open-Close. Просто говорю.


                1. VolCh
                  18.08.2019 00:33

                  А если не повесил? Интерпретируемый язык без 100% реального (а не построчного) тестового покрытия. Или компилируемый даже, но в CI реальной компиляции нет, только линтинг.


                  1. sentyaev
                    18.08.2019 02:01

                    Звучит, как — сами себе создали проблем, но виноват кто-то другой.
                    Если CI не помогает, то решение простое — ребейзим в ветку с фичей мастер, тестим (хоть тестовое покрытие добавляйте, хоть руками) и только потом в мастер. Я к тому, что проблема скорее в процессе, чем в тулах.


                  1. VladVR
                    19.08.2019 17:55

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


      1. sergey-b
        18.08.2019 00:25
        +2

        Feature toggling — это необязательно инструмент организации совместной разработки. Зачастую это способ внедрения бизнес-задач, запуск которых не зависит от разработчика.


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


        1. DukeKan
          18.08.2019 00:40

          Разумный пример, и всё-таки включение/выключение на уровне кода основного приложения выглядит костыльно. После отключения фичи, если она одноразовая — её надо выпилить из проекта, тогда придётся заводить опять ветку в которой все эти if удаляются.
          В идеале, эта функциональность должна включаться зависимостью на уровне системы сборки, и там же выключаться убрав какой-нибудь compile 'company:fifa-extension:1.0' из build.gradle например. А определение места, куда «внедрить» функциональность должна быть на стороне библиотеки-расширения. Навскидку правда пока не могу вспомнить/придумать механизма работы этого


  1. symbix
    17.08.2019 22:13

    Фичетоггл в проекте — фактически запрет на рефакторинг. Не то, чтобы он совсем стал невозможен, но усложняется на порядок.


    Так что — спасибо, нет.


    Проблем с мерджами, кстати, совсем нет, если взять за правило регулярно ребейзить долгоживущие ветки на мастер.


    1. lair
      17.08.2019 22:55

      А откуда в мастере возьмется актуальный код, если все ветки долгоживущие?


      1. symbix
        18.08.2019 02:28
        +1

        Если все ветки долгоживущие, надо что-то в консерватории менять.


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


        И, да, под долгоживущими я понимаю "дольше недели".


        1. lair
          19.08.2019 11:17

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

          Да даже трех-четырех (а я регулярно вижу намного больше одновременно разрабатываемых "сложных фич") достаточно, чтобы устроить ад во время общего мержа.


          1. symbix
            19.08.2019 17:06

            Да не надо дожидаться общего мержа! Ребейзить себе потихоньку.


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


            1. lair
              19.08.2019 17:15

              Да не надо дожидаться общего мержа! Ребейзить себе потихоньку.

              На что ребейзить-то? Еще раз: у вас есть три крупных фичи, долгоживуших. Чтобы вам было, на что ребейзиться, нужно, чтобы эти фичи начали мержить в мастер рано; а "рано" в случае долгоживущей фичи -это "до завершения". В свою очередь, чтобы замержить фичу до завершения, вам надо как-то так сделать, чтобы она, хоть и была замержена, никак не влияла на поведение. И вот тут-то переключатели и помогают.


              1. symbix
                19.08.2019 17:19

                Так мержить по одной, а не все сразу, разумеется. Это все легко координируется, если люди способны общаться друг с другом, а не "закрывать тикеты в джире".


                Допустим, в одной фиче отрефакторили класс, выделив часть методов в отдельный. Куда тут переключатели, простите, засунуть?


                1. lair
                  19.08.2019 17:21

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


                  1. symbix
                    19.08.2019 17:22

                    Вот, один вмержил, другие отребейзились и поправили свой код. Все нормально же!


                    1. lair
                      19.08.2019 17:23

                      Забыли один нюанс: у него долгоиграющая фича, он не может так просто взять и вмержить. Если он вмержит сейчас как есть, в мастер попадет его фича, которая еще не готова к выпуску, и всем испортит настроение.


                      1. symbix
                        19.08.2019 21:29

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


                        А в фичеветке останется то, что собственно к фиче и относится, ну и ок.


                        Вот читаю я это все и создается впечатление, что git-ом пользуются как svn-ом, ну нельзя же так.


                        1. lair
                          19.08.2019 21:31

                          Рефакторинг прекрасно черрипикается в отдельную ветку.

                          Или нет. Если повезло — черрипикается. А если не повезло — нет.


                          1. symbix
                            19.08.2019 22:52

                            Такое тоже бывает. Ничего страшного. Одну смержили, остальные отребейзили, еще одну смержили, оставшиеся тоже отребейзили, и так далее.


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


                            1. lair
                              19.08.2019 22:54

                              Одну смержили, остальные отребейзили,

                              Вернулись на предыдущий шаг: чтобы одну вмержить, надо вмержить незаконченное (потому что, как уже говорилось выше, черри-пик по каким-то причинам не подходит).


                              Понятно же, казалось бы, что feature toggles — они не на каждый день и не на каждую задачу, но бывают задачи, которые они решают успешно.


                              1. symbix
                                20.08.2019 00:40

                                Да нет никаких незаконченных. Что закончили, то и вмерджили.


                                1. lair
                                  20.08.2019 00:42

                                  Ну вот поэтому и ждут до дедлайна, потому что фичу до того самого дедлайна делать и будут. А рефакторинг — это не фича, он отдельной ценности не имеет.


                                  1. symbix
                                    20.08.2019 02:42

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


    1. VolCh
      18.08.2019 00:01

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


      1. VladVR
        18.08.2019 00:34

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


      1. symbix
        18.08.2019 02:29

        Код может не работать и еще по массе причин.


        Разумеется, после каждого мерджа надо прогонять тесты и ревью. Это вроде очевидно.


        У меня вообще правило: каждый раз перед тем, когда фичеветку "передаю" кому-то другому (на тестирование, на ревью), делаю rebase на мастер и прогоняю тесты. Если вижу, что в мастер чего-то намерджили существенное — тоже делаю rebase.


    1. DukeKan
      18.08.2019 00:02
      +2

      Так ведь ещё одна проблема — огромный пуллреквест, при долгоживущей ветке.


      1. symbix
        18.08.2019 02:33

        Решается interactive rebase-ом всей фичеветки, с перегруппировкой коммитов по принципу atomic commits, в "естественном" для чтения порядке.


        Такое вполне удобно ревьюить по одному коммиту последовательно.


  1. sergey-b
    17.08.2019 22:18
    +1

    Я бы вот так делать не стал.


    if (configurationManager.getParameter("is.some.functionality.enabled")) {
        // do some stuff
    } else {
        // do default logic
    }

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


    Надо организовать код таким образом, чтобы ветка else всегда была пустая.


    Например


    if (featureProvider.isFeatureEnabled("JIRA-TICKET-1234")) {
        registerEverywhere(SomeBrandNewFeature.class);
    }

    или


    if (featureProvider.isFeatureEnabledInContext(context, "JIRA-TICKET-4321")) {
        executionPipeline = executionPipeline.next(SomeBrandNewFeature::doSomething);
    }

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


    1. DukeKan
      18.08.2019 00:08

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

      В общем пока непонятно когда это может быть лучше чем просто долгоживущая фичеветка


      1. lair
        18.08.2019 00:27
        +1

        В общем пока непонятно когда это может быть лучше чем просто долгоживущая фичеветка

        Когда вы не хотите постоянно тратить время на актуализацию этой фичеветки.


        1. DukeKan
          18.08.2019 00:35

          Но ведь тоглы придётся постоянно проверять на актуальность на этапе тестирования, вместо подмёрживания мастера в фиче-ветку на этапе разработки. Фичеветку тестируют (в удачном случае) один раз, когда она готова. А тоглы всё время до, и желательно после деплоя на прод. В итоге по трудозатратам может быть даже больше выйдет


          1. lair
            18.08.2019 00:39

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

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


            1. DukeKan
              18.08.2019 00:47

              Ну уж, с таким подходом и тестировщики не нужны, если полагаться только на автотесты. Однако я пока такой сценарий плохо представляю. Тесты не гарантируют работоспособность (как и тестировщики конечно, но это последний и самый «интеграционный» уровень защиты). Тесты только могут гарантировать НЕработоспособность


              1. lair
                18.08.2019 00:56

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


      1. sergey-b
        18.08.2019 00:33

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


    1. VladVR
      18.08.2019 19:07

      Я бы вот так делать не стал.

      Такие ветвления вносят неразбериху.

      Непустая ветка else еще не самое худшее, что може произойти. У нас на портале визард. В JSON лежит конфигурация, степы в порядке следования, дочерние степы и т.п. Разработчик добавляет новый степ. Пока не придумали ничего лучше, чем по if грузить один JSON или другой. Теперь представляем как два разработчика в параллель добавляют два разных степа. Что случится если включить сразу обе фичи? появятся все нужные степы в визарде? очевидно нет. json содержащий все нужные степы просто не существует.


  1. sentyaev
    18.08.2019 02:05
    +2

    Главное — не забывать их выпиливать когда фича закончена.


  1. mrsantak
    18.08.2019 10:20

    Участвовал я в проекте, где практиковался такой подход. Самая жесть начинается, когда фича признается ненужной до того как её полноценно включают. Если это мелкая локальная фича, то все еще нормально, удалил код и дело с концом. А если это более-менее сложная фича, то для неё делались какие-то рефакторинги (которые могут быть еще не закончены), где-то менялось API для этой фичи (при этом эти изменения могла делаться на скорую руку, ибо нет уверенности, что фича действительно уйдет в прод), и вот это все уже не откатишь нормально. В итоге в мастере скапливаются «хвосты» от кучи таких фичей, а архитектура постепенно обрастает костылями.


  1. agent10
    19.08.2019 17:19

    Как раз сейчас тоже думаю о долгоживущих ветках. Что если новая фича это большая переработка старой фичи. В этом случае в основной develop ветке будет жить старый код фичи/новый код фичи/feature toggle.
    1) Во первых это накладывает дополнительный гемор для работы. При этом ничего не мешает сломать еще и старый код…
    2) В конце концов нужна будет «последняя» итерация по выпиливанию старого кода и самой feature toggle
    Плюсы feature toggle пока не вот что бы очевидные.


  1. VladVR
    20.08.2019 08:53

    Во первых это накладывает дополнительный гемор для работы. При этом ничего не мешает сломать еще и старый код…
    Это, кстати первое, что бросилось в глаза, когда я начал работать в проекте со свитчами. Нельзя просто так выпилить старую более никому не нужную логику, и по завершению фичи должен работать и новый код и старый. Нельзя выпилить старую колонку в базе. Это добавляет кучу лишней работы. И новый код приходится писать так, чтобы он не конфликтовал со старым, т.е. кроме того, что старый код надо продолжать поддерживать, в новом коде появляются технические решения, которые не объяснить требованиями. И в будущем, когда приходится еще раз потрогать этот код, идешь к разработчику, который последний раз его трогал и спрашиваешь, почему так, а он отвечает фразой — «исторически так сложилось».


    1. lair
      20.08.2019 11:00

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

      Счастливые люди, у которых нет задачи обратной совместимости. Есть проекты, для которых ситуация "любое деструктивное изменение в данных внедряется две мажорных версии" — норма.


      1. symbix
        20.08.2019 16:44
        -1

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


        1. lair
          20.08.2019 17:00

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


          1. symbix
            20.08.2019 17:23

            Интерфейсы — это контракт. За точно таким же контрактом может стоять какой угодно код.


            Может, раньше в базе была колонка, а теперь ее нет, и значение вычисляется. Какая разница? Снаружи этого не видно.


            1. lair
              20.08.2019 17:25

              Интерфейсы — это контракт. За точно таким же контрактом может стоять какой угодно код.

              Контракт, выраженный в коде, по крайней мере, в некоторых средах разработки.


              Может, раньше в базе была колонка, а теперь ее нет, и значение вычисляется. Какая разница? Снаружи этого не видно.

              Вот только нет никакого "снаружи", интеграционный код напрямую с БД работает. Плохо? Да. Можно поменять? Нет.


              1. symbix
                20.08.2019 17:38
                -1

                Я все же предлагаю рассматривать разумный дизайн ПО.


                Вариантов, когда все сделано через задницу, можно миллион придумать. Для сделанного через задницу появятся и временные костыли, сделанные через задницу (вьюхи, промежуточный сервер, работающий по протоколу СУБД и реврайтящий запросы-ответы...). А так один фиг все переделывать надо.


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


      1. VladVR
        20.08.2019 21:27

        Счастливые люди, у которых нет задачи обратной совместимости.
        И несчастливые те, которые сами себе ее придумали, там где в ней не было необходимости.
        Там где отключаемые фичи требует бизнес, там не откажешся. Например показывать один компонент базовым пользователям и другой компонент премиум пользователям. Но чтоб на свою голову придумывать сложности…
        И самый эпик, наверное, где есть и те механизмы и эти. Если фича включена и пользователь базовый — компонент 1, если пользователь премиум — компонент 2, если фича выключена, то соответственно компоненты 3 и 4. Веселье.


        1. lair
          20.08.2019 21:39

          И несчастливые те, которые сами себе ее придумали, там где в ней не было необходимости.

          Ну, об этом вы с ними поговорите, не со мной.


          И самый эпик, наверное, где есть и те механизмы и эти. Если фича включена и пользователь базовый — компонент 1, если пользователь премиум — компонент 2, если фича выключена, то соответственно компоненты 3 и 4. Веселье.

          Типичное такое A/B-тестирование.