Javascript RORO 模式
— 提高函数可读性
代码可读性非常重要。开发者们总要花费大量时间阅读代码:其他人的、自己的、之前从来没见过的等等。更通俗易懂代码能够帮助团队中的每个人节省大量时间。而可读性通常要和性能做些权衡,但我觉得可读性更重要一些。
我最欣赏的是应用于JavaScript的RORO模式,全名Receive an Object, Return and Object。这个模式的主题是:函数总是应该接受一个对象作为参数,并且返回一个对象作为结果。我们将会把参数和返回值进行解构,使我们更明晰函数中来来去去的都是什么。我写的函数中都是以收到一个对象作为标准形式,我觉得能够简单明了地知道函数中接收到了什么很重要,这个方法来源于我学习Python以及使用kwargs参数形式的一些经验。能够给你要传入的参数打上标签是个不错的方法,而Javascript中的RORO模式可以给我们一些类似的功能去实现。
我们来看一下这个函数调用:
const item = await getItemFromCollection(54391, 'shop');
这种就是我试图去避免的一种写法。虽然函数名挺详细的,我们能推测出这个函数是想要从一个集合中获取一个元素。但是其他信息都是什么意思呢?来用一些之前的经验去猜一猜吧:54391看着像个id,'shop’大概是个集合名称?但这些我们都不太能确定,想要知道具体接口是怎么定义的,我们还要去寻找代码库中声明它的地方。
async function getItemFromCollection(id, collectionName) {
通过查找代码库,我们找到了这个函数的声明处,但这也花费了一些时间。如果我们用RORO模式去写,就无须这一步操作了。
async function getItemFromCollection({ id, collectionName }) {
// do something
};
const item = await getItemFromCollection({
id: 54391,
collectionName: 'shop',
});
当我们声明函数时,需要与结构参数对象有大致相同的语法。而当我们调用时,我们就能够去传递被命名的参数了。我们仅阅读函数调用的地方就能清楚地知道不同参数都是做什么的,也没有必要去寻找函数声明的地方来获得更多信息了。参数的信息现在就是函数调用的一份子,这样既增加了可读性,又减少了去查找代码库或文档的时间,一举两得啊。
令我立刻开始使用这个模式还有一个很重要的原因,那就是很多时候传入的bool类型的参数都让人摸不着头脑。看这个:
someFunctionCall(false);
我是真的不喜欢看到这样写的。bool类型在定义他们的地方之外就没什么有价值的信息了,我也见过用各种方法去优化的。
const variableNameDescribingBooleansPurpose = false;
someFunctionCall(variableNameDescribingBooleansPurpose);
someFunctionCall(/* 为了描述这个bool值所加的一些注释*/ false)
而最好的解决办法就是传入对象并且立刻去解析它。把传入的东西和其描述一起打包传入函数就够一目了然了,无需再做其他事情来让代码变得更加可读。
someFunctionCall({ booleanPurpose: false });
RORO模式有两个部分,刚才我们接触了接收一个对象部分,还有就是返回一个对象。和我们刚才所讲的有些类似,我们的函数将会返回对象,然后需要在实际用到返回数据的地方立刻去解构它。这里有一个优点是能够给予我们一个Javascript原生不支持,而有些其他语言有的功能:一次返回多个元素。
async function runProcess({ processName }) {
// 在服务器上运行进程
// 也许你需要缓存下运行的结果
return { result, wasCached };
};
// 通过解构结果我们就可以获得从函数中返回的多个元素了
const { result, wasCached } = await runProcess({ processName });
if (wasCached) {
// 运行其他进程
}
我个人使用接收对象这部分较多一点。能返回多个元素是不错,但我写的大部分函数只需要关心内部具体的实现就好了。这样看来,还要解构返回值是要比通常直接存在一个变量中要麻烦一点。可能过一段时间回想起来用上一次,我并不会每时每刻都用这种方法。
当然最有用的部分还是在参数命名。尤其是在面对多重参数或者有bool类型的参数时,函数变得更易读了。而多重参数返回虽然很棒,但需要给他们找到合适的地方去应用。这种模式最终能让我们的Javascript函数更加灵活,我在学习了Python和Go之后见识到了很多这些语言为函数所做的优化,因此将其应用在了自己的编码风格上。博采众长对于学习和提高非常有用。