写出好维护的程式码 — 透过模组化设计降低软体复杂度
2025年10月22日
要写出好维护的程式码,其中一个关键是让维护程式码的人,在面对要维护的程式码时,不需要面对整个程式码的系统,而是只需要面对其中的一小部分。当面对某段自己没碰过的程式码,如果该程式码段落很长,就会让人要花比较多时间去理解;反之,假如该段落有好的抽象化,可以让维护者不用关注过于细节的内容,这样读起来会比较容易,也会让整体的可维护性提高。
从比较技术面的角度来谈,上面讲的就是「模组化设计 modular design」的精髓。在这篇文章,我们会来详谈什么是模组化设计,以及在做模组化设计时,有什么要注意的重点。
模组化设计是什么?
如开头谈到,模组化设计是把庞大的程式拆解成不同的模组,这些模组彼此独立,然后当要执行程式时,再把需要的模组整合在一起。这样可人维护者不用一次面对整个系统的复杂度,而是仅用面对单一模组的复杂度。
具体来说,我们在写程式时会用到的类别、函式,或者任何被抽象化的子系统,都可以算是模组。让我们透过一个例子,让大家实际感受一下模组化带来的意义与好处。
相信绝大多数做前后端开发的工程师,在工作上或多或少用过 JSON.stringify 这个方法。这个方法是在 JSON 物件底下,用来把某一个值转为 JSON 字串的方法。
以下是在 MDN 文件中的范例
console.log(JSON.stringify({ x: 5, y: 6 }));
// 会变成 '"x":5,"y":6'
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// 会变成 '"2006-01-02T15:04:05.000Z"'
从模组化的角度来看,JSON 物件本身是一个模组,而该模组能让开发者在使用时,免于接触到 JSON 这个非常复杂的系统。
相信多数用过 JSON.stringify 方法的读者,大概都会觉得这是一个很简单的方法,我们只要把任何值丢进去,就能被转为一个 JSON 字串。但实际上,这个 JSON.stringify 在背后帮我们处理了非常多东西。感兴趣的读者,推荐可以到 json.org 这个网站看一个 JSON 物件背后的细节,会发现可能远比你想像的复杂。
就以 JSON.stringify 来说,在做这个字串化的过程,这个方法需要
- 先检查值是否是有效值 (例如假如是否没有循环引用、有没有副作用)
- 需要对不同值做特别处理 (例如假如是一般字串,要把跳脱字元
\n处理好) - 如果是某个物件,需要递回式地走过并且对其中的每个值做特别处理
- 把处理好的结果,用 JSON 字串规格的格式输出
上面这些,都只是处理字串化本身要做的事情。在这个过程中,还有许多可以去做效能优化的地方,处理起来会变得特别复杂。先前 Google 的 V8 团队就有写一篇《How we made JSON.stringify more than twice as fast》在谈他们把这个方法加速两倍的细节,背后有非常多大家可能想都没想到的事,在 V8 那一端被处理掉。
上面讲了那么多,最关键想要谈的就是模组化。试想,假设今天没有模组化,大家要把某个值转成 JSON 字串,要先把我们上面谈的这些细节先实作出来,这样会有多让人感到崩溃。因为有模组化,我们在面对 JSON.stringify 时,只需要简单地传入一个值,然后呼叫它;而不需要去面对上面讲的那些繁琐的细节或效能优化。
回到上面对模组化的定义,透过模组,我们把一个系统拆成不同的小部分,让面对程式码的维护者,需要去顾及的范围不再是整个系统,这样能让维护起程式码库,变得轻松非常多。
模组化设计的核心要素
在透过具体的案例,了解模组化是什么之后,接着让我们来谈模组化设计的核心要素。
稍微观察一下,上面提到的例子当中的模组,我们可以把它分解成两个部分来看,一个是介面 (interface),另一个是实作(implementation)。介面在做的事情是去描述一个模组要如何使用,要如何跟这个模组互动。而实作的部分则是,这个模组是如何透过程式码实作出来的细节。
进一步来谈,介面就像这个模组的使用说明书,以函式来说,一个函式的的介面就会包含接收哪些参数,以及最后会有什么样的输出。所以对于维护程式码的开发者来说,介面就是在使用该模组时,唯一需要知道的资讯。当然,可能有时候在使用模组时,会需要一些额外的说明 (例如透过注解或者文件),这时候这些额外的说明,会被称为非正式介面(informal interface)。
而实作则是该模组实际的程式码,但这部分也是维护者相对来说不需要关注的部分。就以上面谈到的 JSON.stringify 来说,维护者在用的时候只需要知道介面,不用知道背后那些复杂的实作细节。也因为这点,可以让维护者变得轻松。
阅读更多
关于上面提到的点,如果想做好模组化设计,还有其他要关注的重点,我们在 E+ 成长计划的主题文有更深入的讨论,感兴趣的读者,欢迎加入 E+ 阅读 (连结)。