【问题标题】:How to implement a complex decision in javascript如何在 javascript 中实现复杂的决策
【发布时间】:2019-11-07 17:50:12
【问题描述】:

上下文:

我们正在为注册组件编写逻辑。如果用户未通过身份验证,则应显示该表单。如果/当用户通过身份验证时,它应该重定向到几个地方之一。如果有未读消息,请重定向到第一条消息。如果没有未读消息,则重定向到仪表板。

还有一种情况我们需要处理。当有新消息到达时,用户可以收到一封电子邮件通知,其中包含指向登录表单的链接加上一个带有特定消息 ID 的查询参数。例如:/signin?new_message=42。在这些情况下,如果用户当前未通过身份验证,则应显示登录表单;如果/当用户通过身份验证时,重定向到该特定消息。

我的问题:

我们如何以一种优雅且可扩展的方式来实现它?

怀疑state machine 是完成这项工作的正确工具,但我对其他方法持开放态度。我强调了可扩展这个词,因为这不是代码高尔夫!我正在寻找一种现实生活中的解决方案,该解决方案可以优雅地扩展以在未来包含额外的业务逻辑。

注意:我实际上并不特别关心 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”

产品设计或用户体验建议也忽略了这个问题的重点,例如:“直接从电子邮件通知链接到新消息会是更好的用户体验......”

【问题讨论】:

    标签: javascript design-patterns state-machine finite-automata


    【解决方案1】:

    根据您的描述,确定请求是否来自电子邮件似乎没有意义(或真的不可能)。

    您需要做的就是:

    1. 检查用户是否经过身份验证
      • 如果用户通过身份验证,则检查查询字符串并根据查询字符串重定向,如果没有查询字符串,则重定向到仪表板(您可以为此使用三元运算符)
      • 如果用户未通过身份验证,则显示登录表单
    if(authed) 
        redirect = messageIdFromQueryString ? `/messages/${messageIdFromQueryString}` : '/dashboard';
    else
        redirect = '/login-form';
    

    【讨论】:

      【解决方案2】:

      您给出的上下文和示例将问题显示为“我如何根据几个布尔值的状态做出决定”,对于这个问题,实际上不需要或不希望将问题比连续的 if 语句更复杂,可选使用 return 避免嵌套。

      这已经是干净且可读的代码,并且可能是您所列出的条件的最短和最有效的实现:

      if (!authed) {
        return `/auth`;
      }
      if(clickFromEmail) {
        return `/messages/${messageIdFromQueryString}`;
      }
      if(hasUnreadMessages) {
        return `/messages/${fistUnreadMessageId}`;
      }
      return `/dashboard`;
      

      【讨论】:

      • 感谢您的回答。为了使问题保持​​清晰和最小化,我稍微简化了示例……真实示例也有几个加载状态要处理。例如,当用户点击“页面”时,客户端必须发出 API 请求来验证用户身份,而我们不想在这种情况下显示表单,但我们也不知道是否/在哪里重定向然而。我将修改问题以更清楚地捕捉到这一点。 UI 状态不能清晰地映射到单个布尔值。相反,它们依赖于布尔值的组合。 ?
      猜你喜欢
      • 2020-03-29
      • 2017-05-02
      • 2017-09-23
      • 2013-05-29
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      相关资源
      最近更新 更多