Как реализовать сложное решение в JavaScript - PullRequest
0 голосов
/ 07 ноября 2019

Контекст:

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

Есть еще один сценарий, который нам нужно обработать. Когда приходит новое сообщение, пользователь может получить уведомление по электронной почте со ссылкой на форму входа плюс параметр запроса с идентификатором конкретного сообщения. Пример: /signin?new_message=42. В этих ситуациях, форма входа должна появиться, если пользователь в настоящее время не аутентифицирован;если / когда пользователь проходит аутентификацию, перенаправьте на это конкретное сообщение.

Мой вопрос:

Как мы можем реализовать это в элегантном и расширяемом путь?

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

ПРИМЕЧАНИЕ. На самом деле меня не волнует конкретно javascript, но в рекомендациях StackOverflow особое внимание уделяется специфике, а JS - это язык, который я использую. Следовательно, приемлемый ответ может использовать псевдокод, если он концептуально совместим с javaScript. (Не используйте псевдокод, который работает только в Go)

Оповещение о спойлере! Вот неправильный ответ:

if (authed && hasUnreadMessages && !clickFromEmail) {
  redirect = `/messages/${fistUnreadMessageId}`;
}
if (authed && !hasUnreadMessages && !clickFromEmail) {
  redirect = `/dashboard`
}
if (authed && clickFromEmail) {
  redirect = `/messages/${messageIdFromQueryString}`
}
...

^ Грязный клубок вложенных условных выражений - это проблема , которую мы пытаемся решить.

НЕ мой вопрос

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

Меня также не интересуют решения, основанные на конкретной библиотеке. Пример: «Вы должны просто использовать ComplexSigninLibrary.js»

Советы по дизайну продукта или UX также упускают смысл этого вопроса. Пример: «Было бы лучше, если бы пользователь напрямую связывался с уведомлениями по электронной почте с новыми сообщениями... "

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Ваш контекст и приведенный пример представляют проблему как «как я могу принять решение на основе состояний нескольких логических значений», и для этой проблемы действительно нет необходимости или желания усложнять вопросы дальше, чем последовательные операторы if, необязательноиспользование return, чтобы избежать вложения.

Это уже чистый и читаемый код, а также, возможно, самая короткая и эффективная реализация изложенных вами условий:

if (!authed) {
  return `/auth`;
}
if(clickFromEmail) {
  return `/messages/${messageIdFromQueryString}`;
}
if(hasUnreadMessages) {
  return `/messages/${fistUnreadMessageId}`;
}
return `/dashboard`;
0 голосов
/ 07 ноября 2019

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

Все, что вам нужно сделать, это:

  1. Проверьте, аутентифицирован ли пользователь
    • Если пользователь аутентифицирован, проверьте строку запроса и перенаправьте ее на основе строки запроса, если строка запроса отсутствует, перенаправьте напанель инструментов (для этого можно использовать только троичный оператор)
    • Если пользователь не прошел аутентификацию, отобразить форму входа
if(authed) 
    redirect = messageIdFromQueryString ? `/messages/${messageIdFromQueryString}` : '/dashboard';
else
    redirect = '/login-form';
...