上下文:
我们正在为注册组件编写逻辑。如果用户未通过身份验证,则应显示该表单。如果/当用户通过身份验证时,它应该重定向到多个位置之一。如果有未读消息,请重定向到第一条消息。如果没有未读消息,请重定向到仪表板。
还有另外一种情况我们需要处理。当收到新消息时,用户可以接收到电子邮件通知,其中包含指向登录表单plus带有特定消息ID的查询参数的链接。例如:/signin?new_message=42
。在这种情况下,如果用户当前未通过身份验证,则应显示登录表单;如果/当用户通过身份验证时,重定向到该特定消息。
我的问题:
我们如何以一种优雅且可扩展的方式实现这一目标?
I 怀疑 state machine是完成这项工作的正确工具,但我愿意接受其他方法。我强调了extendible一词,因为它不是代码高尔夫球!我正在寻找一个现实的解决方案,该解决方案可以在将来进行适当扩展以包含其他业务逻辑。
[注意:我实际上并不特别在意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建议也忽略了此问题的要点,例如:“直接从电子邮件通知链接到新消息会更好的用户体验...”
根据您的描述,确定请求是否来自电子邮件似乎没有意义(或实际上没有可能。)>
您需要做的是:
if(authed)
redirect = messageIdFromQueryString ? `/messages/${messageIdFromQueryString}` : '/dashboard';
else
redirect = '/login-form';
给定的上下文和示例将问题呈现为“我如何基于多个布尔值的状态做出决定”,对于此问题,除了连续if语句外,实际上没有必要或不希望使问题复杂化,可以选择使用返回以避免嵌套。