背景
开篇中我们引出了贯穿全局的编码原则:“有着一颗为食用者着想的心”。
那么站在阅读者角度考虑代码本身,就成了自然而然的事情了。
为此,为了让阅读者更容易读懂代码,
上一篇中介绍了一个我常用的编程技巧:让主流程清晰。
采用这种技巧后,代码阅读者就会尽可能少的被 “无用” 信息所干扰。
使代码写的更有层次感,避免一次向读者展出所有的细节。
本文我们将顺着这个思路往前走,
如何才能更高效的做到 “主流程清晰” 呢?有没有常用的技巧可言?
其实是有的,这就引出了本文的主题了:
通过把更多的 “工具” 从 “主流程” 中提取出来,来让我们能表达更复杂的信息。
信息块
说到工具,平时生活中也常见到,留意一下的话,它们简直是到处都在,
手机、键盘、电饭锅、空调、鞋子、衣物、等等等等,
它们的存在大大缩短了我们解决问题的路径。
想要打个电话,我们不用自己直接跟空气中的蜂窝网络进行交互了,
而是只要输入号码,由电话机帮我们处理就行。
每次都从底层处理问题,是很低效的。
我们应当提高当前所处理的最小信息之 “粒度”。
打个比方,如果让我们带领十万步兵打仗的话,
肯定不能 “直接” 去跟着十万个人进行沟通,而是要划分层次 —— “军师旅团营”,
每一层级的长官,只跟自己的直接下属沟通,这样总司令才能管好更多的人。
写代码也是如此,为了让 “主流程” 少包含一些无用的细节信息,
最自然的办法就是,把某些细节信息组装成 “信息块”,
上层只负责处理这些 “块” 就行了,暂时不必关心 “块” 里面是什么。
按照这样的思路进行下去,大信息块中,还可以包含更小的信息块,
如此我们就可以分层管控更多的信息了。
工具箱
那么,哪些代码才适合组装成 “信息块” 呢?
—— 工具
所谓工具 或 “代码工具” 指的是那些可以完整的从 “主流程” 中拿出来的代码,
这些代码还潜在的有更广泛的应用场景。
也就是说,拿出来后,它还可能应用于别的地方。
当然,这里有一个误区是值得说明的,
提取工具的目的,并不是为了复用,而只是为了组装信息块,提高信息的 “粒度”。
事实上,要想编写可复用的代码,是一件需要花费很高成本的事情,
因为,代码并不是放在那里就可以复用了,我们还得告诉用户怎么复用它。
并且复用的同时,也会建立依赖,会产生两个恶果,
其一,被依赖的代码,更难做出变更,因为有人在用着它,必须全面的考虑到位才行,
其二,有过多依赖的代码,会变得更脆弱,每一个依赖出问题,自己都有可能出问题。
所以人们通常会对依赖进行管控,比如版本控制,安全审核,等等。
总而言之,一旦我们准备要写出 “可复用” 代码的话,
那就要小心了,因为这意味着,这些代码需要有充足的文档,有严格的测试,
还得有心理准备:为代码缺陷负责,为用户的咨询负责。
因此,提取工具我们的出发点并不是为了 “复用”,
而是仅仅为了更好的管理它。
组织方式
好了,通过 “提取工具” 我们的 “主流程” 已经非常简洁了,
还剩下最后一个问题,
那就是,这些被提取出来的 “工具” 将如何组织?
我常用的办法,就是充分的利用所用编程语言的 “装配” 手段。
装配粒度从小到大一般可以这么划分:
(1)空行:把做了不同事情的代码,用空行隔开,构成段落。
(2)函数:如果很多行代码,共用了一些信息,那就放到一个函数中。
(3)类 / 闭包:如果多个函数共用了一些信息,那就把它们放到一个 类 / 闭包 中。
(4)模块:如果多个类,共用了一些信息,那么就放到一个模块中。
(5)文件 / 文件夹:如果多个模块,共用了一些信息,那么就把它们放到同一个 文件 / 文件夹 中。
往上继续看的话,其实还有,
多个 文件 / 文件夹,构成了一个 “工程”,
多个 “工程” 构成了一个 “系统”,
多个 “系统” 构成了一个 ...
在这里我有两个体会,值得分享一下。
其一,系统架构受制于开发这些系统之人员的组织架构(康威定律)。
其二,软件架构的艺术在于划分边界,使得边界处的信息流更小。
总之,以上工具的组织方式,谈到实质还是在管理 “信息”。
每块信息都有人负责,并且让这些人能尽量避免频繁沟通。
从一开始我们关心 “食用者”,就意味着编码技巧,不得不考虑人员因素。
结语
思路是有延续性的,为了做到 “为食用者着想”,我们想到让 “主流程” 清晰,
以减少阅读者的一次看到的信息量,
为了让 “主流程” 清晰,我们想到将 “工具” 提取出去。
这些 “代码工具” 构成了粒度更大的 “信息块”,
大大提高了我们掌控全局的能力。
最后我们还提到了 “代码工具” 如何管理、如何组织的问题,
不同的人会有不同的信息组织方式,
但指导原则是不变的,那就是让负责维护这些代码的人,避免频繁沟通。
信息构成的层次性,跟人员组织的层次性,应当是等价的。