谈到模块化,我们一般指把逻辑或功能上能自成一体的代码装成一个模块,大概率它对外界而言就像提供了一系列接口的黑盒子。
契机
前些日子接到的任务是(用 Javascript)写一个数据生成工具,说白了就是生成若干个 csv 文件。功能上不难,就是为了让数据在 UI 上看起来漂亮点,会做一些随机化之类的处理。到了后来,大哥们说要基于老的 csv 去生成新数据(本质上是对一颗老树进行子节点的拓展)。由于一开始就是功能导向,基本上没做逻辑划分和接口设计,后面需求变化导致代码有点膨胀(其实加上注释也就不到一千行代码)。于是我发现我看自己的代码已经有点吃力了…
后来我发现新加的需求可以用另一种稍微优雅的方式去描述,而不是把一份逻辑在两个地方写两次。这种行为是有点致命的,发现这种问题一般而言就是没做好抽象。
此外,因为我把逻辑全部扔在一个文件中,各种嵌套函数的定义,还用到闭包去减少一些状态参数的传递。PS: 扔在一个文件主要是因为当时连 require()
都不会用……
这两天因为 csv 的 entity 定义变化巨大,让我有理由真正把这个小工具重构一下。我发现 OOP 这一套还是很有用的,就算你强行划分,大部分情况下也会让你的代码结构看起来很清爽。这次重构其实有点像从 面向过程 到 面向对象。
谈到 OOP ,我们在说什么
说到 OOP ,一般都会有诸如 『封装』、『继承』、『多态』、『抽象』之类的字眼,如果一定要选,我觉得最重要还是封装和抽象吧,它们相对而言比较 fundamental 。
最近跟着一个教程在写解释器,确实比较之 OOP 。比如类内变量去存储一些中间状态和中间结果,这样一个很明显的好处就是可以减少函数调用时的参数传递,可以认为就是一个全局 binding 。又比如把不同的功能(Scanner Parser)划到不同的类……
这些中间状态和结果其实是对象的状态,也就是导致同一函数调用有不同结果的元凶(我们称之为副作用(side effect))。
形如 Java 这样的语言强行让你以类为单位去组织代码,在限制你创造性的同时其实也会保证代码可读性的下限。
话题可能拉得太开了,其实我也说不明白,就是感觉对一些东西有了新的认识。先这样(逃