Как стать автором
Обновить

Комментарии 10

Только что, на сайте hh.ru, при отклике на вакансию, получил:
"Произошла ошибка, попробуйте ещё раз".
Решил посмотреть как в hh.ru делают программы.
Вижу: носят воду решетом - решают сложность увеличением сложности.

Так как Ваш продукт лидер и пусть он работает хорошо - не буду иронизировать.
Проблемы с флагами давно уже решил Шалыто Анатолий Абрамович

Сила хабра - ошибка исчезла, отклик отправился. Спасибо.

Привет.
Давайте разберём всё по-порядку.

1. На сайте случилась ошибка
Если вы отправите нашей службе поддержки как можно больше данных об инциденте, мы получим шанс это исправить.

2. Решают сложность увеличением сложности
Укажите, где именно случилось «увеличение сложности»? Мы столкнулись с проблемой merge-конфликтов, довольно дешёвым способом её решили. Захотели собрать разбросанные по кодовой базе флаги — и тоже сделали это довольно простым способом.

3. Проблемы с флагами давно уже решил Шалыто Анатолий Абрамович
Пробовал нагуглить его статьи про merge-конфликты, feature toggles, feature flags, не нашёл. На сайте, который вы указали, тоже не нашёл в публикациях подобных статей. Укажите конкретную статью, чтобы и другие читатели могли с ней ознакомиться.

4. Ошибка исчезла, отклик исправился
Рад слышать.

День добрый!

С удовольствием помогаю совершенствовать полезный сервис hh.ru.

Есть html версия книги:
Шалыто А.А. Switch-технология. Алгоритмизация и программирование задач логического управления. СПб.: Наука, 1998., 628 с
Прям первое вхождение слова флаг.

Ютуб Шалыто А.А. "Автоматное программирование". 2019 год, с 6ой минуты.

Вся наука от Шалыто, как устав вооружённых сил - потом и кровью.

Про увеличение сложности:
"Есть множество способов собрать разбросанные по кодовой базе модели в единый список;".
Надо не собирать, надо не разбрасывать.

Снова давайте отвечу по пунктам.

1) Посмотрел видео, по диагонали почитал книгу.
Моя статья мало имеет отношения к тому, о чём говорит профессор Шалыто =)

Он рассказывает о построении логики программ на основе стейт-машин / конечных автоматов (или об «автоматной парадигме программирования», если в терминах профессора). Стейт-машины — полезный инструмент, который Android-разработчики давно взяли на вооружение. Мы в hh практически каждую фичу описываем именно с их помощью.

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

По сути, о таких простых флагах и идёт речь в статье.

Иногда флаги появляются и для описания переходов внутри стейт-машин, кстати. Немного странно делать 2 стейт-машины в этом случае, гораздо проще описать дополнительный if для одного перехода.

P.S. Лично мне показалось, что структура тех стейт-машин (автоматов), о которых рассказывает профессор, недостаточно гибкая. В частности, не увидел в структуре способе отдать единичное событие из машины наружу. А такое иногда требуется — например, показать снекбар при переходе в состояние ошибки. Каким-то полем внутри State-а это делать неудобно.

2) «Надо не собирать, надо не разбрасывать.»

Недостаточно понятная для зумера сентенция =) Уточните, что имеете в виду, как именно надо было «не разбрасывать»?

Вот есть проблема: если «не разбрасывать» и помещать код в один-единственный файл (неважно, в виде enum-а, в виде отдельных функций или ещё как-нибудь) — появятся merge-конфликты, от которых мы хотели уйти.

Если размещать в разных файлах (то бишь, «разбрасывать»), merge-конфликты уходят, но надо будет собирать всё обратно в единый список.

Хочется увидеть конкретное решение, которое вы предлагаете, реализацию в коде. Необязательно на Java, но тогда есть шанс, что вы используете какую-то специфичную для определённого языка конструкцию, которой просто не существует для Android-разработки.

Аки богатырь, один из массовки хабра, радею за улучшение hh.ru.

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

"Не разбрасывать" я имел ввиду: не создавать сущности без надобности.

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

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

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

Спасибо за статью, описан достаточно зрелый подход и ресерч мне понравился.

Только с генерацией экспов - немного не хватило ещё одного приема: codegen'a с помощью Gradle.

У этого подхода есть один плюс: мы можем вручную добавить коллекцию в build директорию проекта, и увидеть все эксперименты в проекте без танцев с бубном, необходимости запускать дебажное приложение и вносить что-то руками.

Спасибо за комментарий!

Про codegen через Gradle — расскажите поподробнее, не очень понял, как бы это делалось. Если есть какие-то статейки на примете — отлично.
Обычно именно с Gradle-ом начинаются «танцы с бубнами» =)

Зачем мы запускаем дебажное приложение — чтобы менять значение флагов внутри приложения. Это полезно и для тестировщиков, и для разработчиков, так что мы от этого не уйдём. Просто увидеть все эксперименты в проекте можно было бы и навигацией по коду, типо «найти всех наследников интерфейса Experiment» — нам этого недостаточно =)

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

Привет! Извиняюсь за поздний ответ)

Мы в Surf когда-то писали анализатор kotlin-файлов на основе Gradle, который валидировал, что экран, который указан в точке входа в фичу, существует в проекте (не спрашивайте, почему это было сделано не через линт).

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

Плюс, есть более оптимальные решения (тот же kapt/ksp/compiler plugin), позволяющие делать аналогичные действия.

Я кстати для похожей задачи решил использовать ksp. Мне очень понравилось, потому что получилось обойтись без рефлексии и build time тоже почти не пострадал. Вначале тоже хотели использовать ClassIndex, но в нашем случае необходимо было использовать в код, собирающий информацию об экспериментах в проде, и это рождало несколько проблем:

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

  2. При обращении к ServiceLoader.load, он считывает и инстанциирует все эксперименты из файла, а если этот файл достаточно большой (например, несколько сотен экспериментов) - это может сильно сказаться на производительности.

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

Надеялся, что мы поняли друг друга, но ...

Сегодня от hh.ru на этот же мой почтовый адрес пришло:
"Вы зарегистрировались на hh.ru, и это хорошо. Но пока работодатели не могут отправлять вам приглашения на работу. Как это исправить?
Просто создайте резюме ..."

Флаги продолжают делать жизнь разработчика насыщенней?

"Пусть реют флаги над полками" :-)


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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий