ORGPROG Telegram 356
Программирование на флагах

Недавно я упомянул этот термин в одном и постов и получил неожиданно большое количество комментариев "что это?". Тема заслуживает раскрытия, поэтому пост.

Возьмем пример с sql:


SELECT *
FROM users
WHERE active = 1;


Почти наверняка это поле из двух состояний активен/не активен (1/0), где активность определяется подтверждением емейла. В Postgresql это было бы true/false.

В целом, этот код выглядит совершенно нормально и очень хорошо работает. До поры до времени. А потом выясняется, что «неактивный» бывает как «удалённый», так и «заблокированный». Или, например, мы (бизнес) захотим давать работать на сайте тем кто зарегистрировался, но не подтвердил емейл. Подтверждение емейла будет работать как способ получить больше функций. В сумме мы получаем:

⁃ зарегистрированный
⁃ активный (подтвержден емейл)
⁃ удаленный
⁃ забаненный

Поскольку в базе уже есть active, то разарботчик, вероятно, пойдет по наиболее легкому пути - начнет добавлять новые флаги. Это просто и не требует хитрых миграций, чтобы обеспечивать обратную совместимость (для zero downtime). В итоге в базе появятся флаги:

active, email_convirmed, banned, deleted

и с этого момента начинается то самое программирование на флагах.

Вместо одной колонки состояния появляется несколько несвязанных булевых полей, которые можно комбинировать как угодно:

Комбинаторный взрыв состояний - пользователь может быть active = true, но при этом banned = true и deleted = true. Что это значит? Он активен или нет?
Неявные правила - чтобы понять, что такое «активный пользователь», нужно лезть в код и смотреть, как именно проверяются флаги (active && !deleted && !banned && email_confirmed)
Сложность изменений - добавление нового флага или изменение бизнес-логики требует правок во множестве мест, потому что условия размазаны по коду и SQL-запросам.
Повышенный риск багов - достаточно забыть один флаг в проверке и все, приплыли.

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

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

Мы кстати с этого и начали, когда перечисляли возможные состояния пользователя.


type UserState = 'active' | 'banned' | 'deleted' | 'waiting_email_confirmation'


Фактически такой подход гораздо лучше ложится на то, как мы думаем об этом, чем флаги. Более того, это и намного нагляднее с точки зрения кода. Таким образом мы сразу решаем проблему синхронизации, переход из одного состояния в другое это одно действие и отсутствие багов в стиле "флаги не согласованы"

Есть еще один немаловажный плюс. Допустим у нас изначально два состояния и мы решили, что не будем бежать впереди паровоза. Мы делаем в базе boolean и попадаем в ситуацию, что когда добавится третье состояние, придется менять тип колонки на строку и все значения внутри него. Опытные разработчики сразу будут этому сопротивляться, потому что ломать обратную совместимость в базе нельзя, поэтому правильным способом, будет создать новую колонку и выполнить миграцию туда. Оно нам надо? То есть использования состояния это безопасно и расширяемо в отличие от флагов.

Но даже этого может быть недостаточно. Следующим шагом будет использование конечных автоматов https://github.com/eram/typescript-fsm (в том случае если нужна реакция на переходы, а сама структура переходов не линейная)

Ссылки: Телеграм | Youtube | VK
1👍14131🔥13🤔3👀1



tgoop.com/orgprog/356
Create:
Last Update:

Программирование на флагах

Недавно я упомянул этот термин в одном и постов и получил неожиданно большое количество комментариев "что это?". Тема заслуживает раскрытия, поэтому пост.

Возьмем пример с sql:


SELECT *
FROM users
WHERE active = 1;


Почти наверняка это поле из двух состояний активен/не активен (1/0), где активность определяется подтверждением емейла. В Postgresql это было бы true/false.

В целом, этот код выглядит совершенно нормально и очень хорошо работает. До поры до времени. А потом выясняется, что «неактивный» бывает как «удалённый», так и «заблокированный». Или, например, мы (бизнес) захотим давать работать на сайте тем кто зарегистрировался, но не подтвердил емейл. Подтверждение емейла будет работать как способ получить больше функций. В сумме мы получаем:

⁃ зарегистрированный
⁃ активный (подтвержден емейл)
⁃ удаленный
⁃ забаненный

Поскольку в базе уже есть active, то разарботчик, вероятно, пойдет по наиболее легкому пути - начнет добавлять новые флаги. Это просто и не требует хитрых миграций, чтобы обеспечивать обратную совместимость (для zero downtime). В итоге в базе появятся флаги:

active, email_convirmed, banned, deleted

и с этого момента начинается то самое программирование на флагах.

Вместо одной колонки состояния появляется несколько несвязанных булевых полей, которые можно комбинировать как угодно:

Комбинаторный взрыв состояний - пользователь может быть active = true, но при этом banned = true и deleted = true. Что это значит? Он активен или нет?
Неявные правила - чтобы понять, что такое «активный пользователь», нужно лезть в код и смотреть, как именно проверяются флаги (active && !deleted && !banned && email_confirmed)
Сложность изменений - добавление нового флага или изменение бизнес-логики требует правок во множестве мест, потому что условия размазаны по коду и SQL-запросам.
Повышенный риск багов - достаточно забыть один флаг в проверке и все, приплыли.

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

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

Мы кстати с этого и начали, когда перечисляли возможные состояния пользователя.


type UserState = 'active' | 'banned' | 'deleted' | 'waiting_email_confirmation'


Фактически такой подход гораздо лучше ложится на то, как мы думаем об этом, чем флаги. Более того, это и намного нагляднее с точки зрения кода. Таким образом мы сразу решаем проблему синхронизации, переход из одного состояния в другое это одно действие и отсутствие багов в стиле "флаги не согласованы"

Есть еще один немаловажный плюс. Допустим у нас изначально два состояния и мы решили, что не будем бежать впереди паровоза. Мы делаем в базе boolean и попадаем в ситуацию, что когда добавится третье состояние, придется менять тип колонки на строку и все значения внутри него. Опытные разработчики сразу будут этому сопротивляться, потому что ломать обратную совместимость в базе нельзя, поэтому правильным способом, будет создать новую колонку и выполнить миграцию туда. Оно нам надо? То есть использования состояния это безопасно и расширяемо в отличие от флагов.

Но даже этого может быть недостаточно. Следующим шагом будет использование конечных автоматов https://github.com/eram/typescript-fsm (в том случае если нужна реакция на переходы, а сама структура переходов не линейная)

Ссылки: Телеграм | Youtube | VK

BY Организованное программирование | Кирилл Мокевнин




Share with your friend now:
tgoop.com/orgprog/356

View MORE
Open in Telegram


Telegram News

Date: |

How to Create a Private or Public Channel on Telegram? There have been several contributions to the group with members posting voice notes of screaming, yelling, groaning, and wailing in different rhythms and pitches. Calling out the “degenerate” community or the crypto obsessives that engage in high-risk trading, Co-founder of NFT renting protocol Rentable World emiliano.eth shared this group on his Twitter. He wrote: “hey degen, are you stressed? Just let it out all out. Voice only tg channel for screaming”. Other crimes that the SUCK Channel incited under Ng’s watch included using corrosive chemicals to make explosives and causing grievous bodily harm with intent. The court also found Ng responsible for calling on people to assist protesters who clashed violently with police at several universities in November 2019. The Standard Channel ‘Ban’ on Telegram
from us


Telegram Организованное программирование | Кирилл Мокевнин
FROM American