函数思考,第一部分:输入/输出模式

释放双眼,带上耳机,听听看~!

函数思考,第一部分:输入/输出模式

介绍
理解函数的方式。

如果您来自函数式编程背景,我将要说的内容对您来说可能并不新鲜。但是,我知道有些开发人员不习惯强类型,当他们想到函数时,Hindley-Milner 的表示法并不是他们脑海中首先浮现的东西。我把这篇文章写给那些人。

Input/Output 模式
我们知道函数接受参数并返回一个值。我们有时会忽略的是,这个特性是一个非常强大的设计模式,我们可以用它来编写更好的函数。

首先尝试通过回答以下两个问题来编写任何函数:

这个函数的输入是什么(它接受什么参数)?
这个函数的输出是什么(它返回什么数据)?
这样做可以让您将技术细节放在一边,专注于作为 input/output 操作的函数,事实上,它确实如此。您给出的答案可能暗示了某些实现细节,但最重要的是,它们在编写任何实际代码之前很久就定义了对函数职责的明确约束。

你可以对你的答案使用抽象类型。例如,一个函数可以接受一个苹果列表并返回一只快乐的狐狸。这种类型抽象进一步将 call 签名与 implementation 分离。

让我们将其付诸实践。比如,你需要编写一个验证表单字段的函数。影响字段验证的因素有很多,但你可以把这些放在一边,先回答 Input/Output 问题:

我的函数接受一个字段;
我的函数返回验证结论 ()。boolean
写下来后,这些答案表示函数的调用签名:

function validate(field: Field): boolean;

此时您可能不知道类型可能是什么,但您知道它代表什么。总的来说,该函数也可以这样说:无论哪些因素影响字段的有效性,您最终都必须解析为布尔值。定义的输入和输出起到限制作用,防止我们的函数在截止日期驱动的开发过程中变得过于智能。这确保了我们编写的 logic 位于 function 的职责范围内,并且保持简单,同时满足 single responsibility 和 KISS 原则。Fieldvalidate

采用此模式并不意味着您应该立即使用 TypeScript 或任何其他强类型语言重写代码。首先,它是思考函数的方式。将输入和输出记录在 JSDoc 块或 Sketchbook 中是可以的。从改变您的思维方式开始,工具就会随之而来。

类似于在制作适当的 UX 之前将用户的需求放在首位 decisions 中,您需要考虑函数接受和返回哪些数据 为了建立其未来实施的边界。

按比例排列
考虑使用这种模式的函数固然很好,但是通常由多个函数组成并表示更复杂的逻辑的实际操作呢?

事实是,即使是最复杂的函数也可以写成一组连续执行的较小函数。当您以这种方式处理任务时,您可以专注于一次设计每个单独的函数。但是,将函数隔离在一起是危险的,因为您最终可能会得到多个无法组合在一起的拼图。有一个函数组合规则可以避免这个问题:

如果两个函数的输出可以用作另一个函数的输入,则两个函数是可组合的。

知道了这一点,让我们实现一个相当复杂的操作,该操作接受用户并返回其所有帖子下的点赞数。为了防止复杂性,我们可以将此操作描述为一系列步骤:

获取用户 → 获取用户的帖子 → 获取帖子的点赞数量

这些步骤中的每一个都是一个函数,我们可以应用 Input/Output 模式来设计其调用签名,同时牢记组合原则。

const getUser = (id: string) => User
const getPosts = (user: User) => Post[]
const getTotalLikes = (posts: Post[]) => number

这种功能链的高级概述使您能够不受干扰地跟踪数据流,并突出显示 logic 中的潜在问题。此外,这只是一个有趣的练习。

最后,函数是关于转换数据的,因此请使用所有方法 可用于确保转换的连贯性和高效性。

还有一件事!
关于 Input/Output 方法还有一个隐藏的宝石。假设你用 “my function accept a list of strings and return a number” 来回答这些主要问题。恭喜,您刚刚为您的函数编写了一个单元测试!

expect(myFunc(["a", "b"])).toEqual(2);

此模式的结果可能会反映在测试方案中,从而使用实际的单元测试来支持函数设计决策。这鼓励 TDD(测试驱动开发)和 BDD(行为驱动开发),因为我们通过描述函数的输入和输出来表达函数的意图。

总结
关注函数的 input 和 output types 定义了该函数的简明规范:

函数的调用签名;
该函数的最小单元测试。
根据规范实现事物是一种愉快且安全的体验,我绝对建议您习惯。

后记。

如果你想了解更多实用的模式和功能设计的方法,请点赞这篇文章,并在评论中告诉我。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
技术教程

如何以开发者的方式向人类提问:一份指南【原文】

2024-8-30 17:52:10

技术教程

理解 TypeScript 泛型

2024-9-2 15:11:06

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索