无绪 (Cluelessness) 由 Martin Rinard 提出。他在演讲时指出:
在开发和维护软体系统时,应该避免让开发人员深入了解系统。
因为人的大脑可以处理的资讯有限。若要建立一个日益变大的应用程式,就必须学习「如何让每个开发人员在不了解整个应用程式的情况下,也能完成软体开发」。
“无绪” 并不是一个贬义词。它用来区别两种层次的理解水平。
浅层理解:指对事物的了解程度仅限于掌握使用方法即可。深层理解:指对掌握了事物背后的原则、规律、原理。在日常生活中的“无绪”
生活中我们通常只需要用到 浅层理解。例如,刷牙不需要知道化学式。不需要理解冰箱原理就可以冷冻食品。当然,也有一些人需要了解更深入的内容。像是冰箱的维修人员就要了解较深入的领域知识。但即便如此,维修人员所需要的知识仍属于 浅层理解,因为他们也不需要了解事物背后的每个小细节和原理。
当然也可以学习每件事物背后的知识原理,但是必要性与 CP 值通常不大。因此大多数人在日常生活中只需要 浅层理解 就足够了。
软体开发中的“无绪”
在软体开发中,“无绪” 也表示大部分的时间中,开发人员只需要 浅层理解 就足以应付工作。这里的 浅层理解 并不是指开发人员不需要懂得编写程式。以下举个例子来说明软体开发中的 浅层理解 与 深层理解 之间的差异。
「电子商务网站」:
某天 PM 告知下一个专案是「电子商务网站」。那么,实作这个网站有两种做法:
实作方法一:
在专案初始阶段: 我需要打开 HTTP 协定的文件,解析 HTTP 传输格式、研究如何实现 POST、GET 请求....等等。 此外还要阅读 RFC 文件,并实现文件中的各项内容。 全部都搞定后才能开始打造「电子商务网站」。
实作方法二:
在专案初始阶段,在作业系统中下载并安装 Apache、PHP、MySQL, 设定妥当后即开始打造「电子商务网站」。
相信 实作方法二 才是大家熟悉开发的方式,因为现代软体都是基于组件组装出来的,没有人需要独自从头到尾完成所有内容。在一个作业系统上安装 Web 服务并开始编写 HTML,对现在的开发人员来说是易如反掌。但事实上光是 Web 服务就已经複杂到极点,应该没人敢说自己了解 Web 服务的所有内容。这一现象正是 浅层理解 的体现,让开发人员在大部分的时间中,只需要掌握系统、框架、程式库的使用方法,即可以将现成的组件应用到自己的应用程式,或是在组件上堆叠自己的应用程式。
设计原则中的“无绪”
我们的目标是找到一种软体开发的实践方式:让开发人员不用深入了解所有组件或者模组的实现原理,仅用最少的知识就可以很好地完成自己所需要的功能。这种开发方式被称为「选择性无绪(selective cluelessness)」。
选择性无绪 的思维,正好符合软体设计原则的 紧凑性。当一个程式具有紧凑性时,即具有「易于理解、使用、组合」等特性。这些特性让使用者几乎可以不用阅读文件,即可自然而然的使用这些程式。但是要注意的是,紧凑性并不等同于「容易学习」。
以下提供一个紧凑与不紧凑的範例:
原生的 JavaScript 的 Date 物件是不紧凑的:
// 时间格式转换var now = new Date(); var year = now.getFullYear(); var month = ("0" + (now.getMonth() + 1)).slice(-2); var day = ("0" + (now.getDate() + 1)).slice(-2); var hour = ("0" + (now.getHours() )).slice(-2); var minute = ("0" + now.getMinutes() ).slice(-2); var second = ("0" + now.getSeconds() ).slice(-2); year + '/' + month + '/' + day + ' ' + hour + ':' + minute+ ':' + second;
moment.js 的 moment 物件是紧凑的:
// 时间格式转换moment().format('YYYY/MM/DD HH:mm:ss');
若程式设计得当,维护人员就可以使用 浅层理解 来学习你的程式。若程式设计得不够紧凑,维护人员往往需要将头脑切换成 深层理解 的模式来探索你的程式码,并学习是如何运作的。
因此编写程式的过程中,应该时时刻刻想着如何让你的程式变得 “无绪”,让使用者可以用最少的力气学习你的程式。这样的设计思维适用于「函式、类别、模组、类别库、架构、框架以及系统」的情境。也就是 Martin Rinard 所说的:
软体设计要尽可能做到 “无绪”。让开发人员可以在对系统很少了解的前提下,仍然可以完成开发的工作。
延伸阅读
自学时应该看破“无绪”文章内容整理自以下书籍并加以归纳与简化:
软件框架设计的艺术(Practical API Design)UNIX编程艺术