functional-programming - 函数式编程 if 语句
问题描述
我在 js 中有类似于以下伪代码(数字是占位符):
if (user.isActive()) {
if (user.hasManyComments()) {
if (user.isSpecial()) {
return {ok: true}
} else {
return {ok: false, error: 'has comments'}
}
} else {
return {ok:true}
}
} else {
return {ok: true}
}
} else {
return {ok: false, error: 'err'}
}
如何将代码同时翻译成功能性和可读性?
我更喜欢以 JS 为例。
我知道在 FP 中您没有复杂的 if 语句,但在某些情况下很难删除复杂的 if 语句。
图书馆可供使用。
如果我只有一个级别的 ifs 没问题,但如果级别达到 3,4 级别就很难了
谢谢
解决方案
对于此代码:
if (user.isActive()) {
if (user.hasManyComments()) {
if (user.isSpecial()) {
return {ok: true}
} else {
return {ok: false, error: 'has comments'}
}
} else {
return {ok:true}
}
} else {
return {ok: true}
}
我认为它只需要一些重构酱。首先,您有 3 个好的路径 ( return {ok: true}
) 和 2 个可能结果的错误路径,但是您有 4 个返回语句。让我们看看我们是否可以将其降低到 1-1 的比例:
return !user.isActive() || (!user.hasManyComments() || user.isSpecial()) ?
{ok: true} :
{ok: false, error: 'has comments'};
经验法则:您应该检查一次条件,并且没有比实际代码路径更多的返回语句。坦率地说,我不一定认为它比你的原版更具可读性,即使更短。请注意,我基本上已经打过它,这里有一定程度的中间。为了使它更具可读性,因为我们使用了很多否定,我们可以做这样的事情:
const tooManyComments = user.isActive() &&
user.hasManyComments() &&
!user.isSpecial();
return tooManyComments ? {ok: false, err: 'err'} : {ok: true};
现在我们只检查错误路径,否则返回 true。
回复评论中的问题
如果你想让它更短,你可以通过滥用逗号操作符。但这可能是一个更清洁(并且仍然简短而简单)的解决方案:
const hasTooManyComments = user => (user.isActive() &&
user.hasManyComments() &&
!user.isSpecial());
const response = hasTooManyComments(user) ?
{ok: false, err: 'err'} :
{ok: true};
你也可以让它成为一个函数:
const generateResponse = user => hasTooManyComments(user) ? ...
推荐阅读
- javascript - Cordova/Javascript 录音
- java - 在 Java 中设置两个不同 API 的 Classpath 的问题
- css - 有没有办法在网格项目之间共享背景?
- osgi - 如何在同一个插件中处理 2 个 OSGi 声明式服务包组件?
- c# - 生成 excel 文件时 NPOI 无法评估公式
- ios - 使用全色深度 MTLTextureDescriptor 创建 MTLTexture
- java - 如何显示使用媒体播放器播放的 mp3 文件的当前持续时间和总持续时间
- vb.net - 如何使用同一个变量引用多个类名?
- python - 针对整个文件目录执行功能
- c++ - 如果类型(不)相等,C++ 是否可以有条件地编译代码