相比于第一个只需要一次取数,一次setData,第二个性能无疑更低,但是可维护性变高了,3 件事情都被拆分出来,后面修改代码时候,我可以追加一个 doD 而不是再次把第一份代码中逻辑整理清楚再小心翼翼的修改代码。
命名与注释 There are only two hard things in Computer Science: cache invalidation and naming things.命名与缓存失效是两大难题,今年讲了不少缓存问题,同时,命名的确是很困难的一件事情。通过一句话来解释你们在做什么事情,通过一句话来解释一件事的意图。
不说在程序世界中,在现实世界中也是如此。例如: 《震惊!xxx居然xxx》等新闻,虽然说看完后都会想要骂一句,但是,正如这样的名字才能吸引人家点击进入,让人情不自禁的被骗一次又一次。所以在项目没有发布前,要取一个简单而又好记的名字。
但在程序内部,我们不需要“骗取”人家的点击量,反而是要务实点,不要欺骗另外的同伴,比如说写了一个简单的名字,结果内部却封装了很多的业务代码。同时我认为这也是函数越写越短的理由,因为大家难以通过命名来解释那一大坨代码的意图。所以,需要编写可以自我解释的代码,而这种代码最佳实践就是好的命名。
对于开源代码,你往往会发现,这些文件开头都会有一系列注释,这个注释告诉我们了这个模块的意图与目的。让你无需看代码就可以进行开发。
对于业务开发而言,仅在你不能通过代码清晰解释其含义的地方,才写注释。在多个条件下都无法解释你的代码。
项目名模块名文件名(类名)函数名(方法名)
这并不是让你不写注释。但是我觉得更多的注释应该放在数据结构而不是代码逻辑上。聪明的数据结构和笨拙的代码要比相反的搭配工作的更好。更多的时候,看数据结构我能了解业务是如何运行的,但是仅仅看到代码并不能实际想象出来。
实际上,随着时间的推移,代码做出了许多改动,但注释并没有随之修改,这是一个很大的问题。注释反而变得更有欺骗性。
这里也提供一篇 export default 有害 的文章。我觉得 export default 导出一个可以随意命名的模块就是一种欺骗性代码(随着时间的推移,该模块的意图会发生变化)。
考虑场景没有放眼四海皆准的方案,所以我们必须要考虑到场景的问题,我们总是说可修改性,可读性是第一位的(往往可读,可修改的代码性能都不差)。但是如果是急切需求性能的场景下,有些事情是需要再考虑的。
if 是业务处理中最常用的,在每次使用前要考虑以下,哪个更适合作为主体,哪个更适合放在前面进行判断。如果有两个维度上的参数,一个是角色,一个是事件。一定是会先判断角色参数,然后再去判断事件参数,反之则一定不好。因为前者更符合人的思维模式。在同一维度下,至于哪个放前面,一定是更多被使用的参数放在前面更好,因为更符合机器的执行过程。
就像在 if 中你究竟是使用 else 还是 return。大部分情况下处理业务逻辑互斥使用 else,处理错误使用return。因为这样的代码最符合人的思维逻辑。
但是在这里我也要举出来自《代码之美》的例子,在第五章中,作者 Elliotte Rusty Harold 设计了一个 xml 验证器,其中有一段在验证数字字符:
public static boolean isXMLDigit(char c) { if (c >= 0x0030 && c <= 0x0039) return true; if (c >= 0x0660 && c <= 0x0669) return true; if (c >= 0x06F0 && c <= 0x06F9) return true; // ... return false }这个优化之后如下:
public static boolean isXMLDigit(char c) { if (c < 0x0030) return false; if (c <= 0x0039) return true; if (c < 0x0660) return false; if (c <= 0x0669) return true; if (c < 0x06F0) return false; if (c <= 0x06F0) return true; // ... return false } 全局思考,善于交流软件开发已经不是一个人打天下的时代了,你要不停的触达边界。在前后端分离的时代,前端可以不知道数据库如何优化,后端也可以不清楚浏览器的渲染机制,但是却不能不明白对方在做什么。否则等于鸡同鸭讲,也会浪费时间。在开发时候,把一段逻辑放在那一端取决安全的思考以及简化逻辑。