最早接触的计算机系统,是一家企业的FreeBSD的数据服务器。由于我家老大在其中工作,所以分配给我一个帐号,我就天天在其中尝试一些命令,who了,vi了,cc了什么的,当时,系统只是一个黑屏绿字的终端,比较无聊。后来上了大学,在自己的机器上装了Fedora Core Linux,用来学习数据结构,编译原理,操作系统原理等等,十分有意思。现在想来,*nix系统中的很多思想仍然是非常有用的。
大二的时候学习完软件工程后,看了一本书:《UNIX编程艺术》 ,收获确实挺多,现在也工作了一段时间了,就把*nix系统中的一些简单的思想做个小小的总结吧。
- 保持简单
每个程序都应该尽可能的简单(当然不是Hello, world级别的简单)。简单的好处是显而易见的,易于维护,易于重新设计,代码易于被读懂等等。“当你想要设计一种复杂的文件格式时,最后的解决方法是躺下来,等这种冲动过去。” - 降低耦合
每个程序尽量只做一件事,并且要做到最好。这样设计出来的系统,耦合度非常底,程序中模块与模块间耦合降低,很容易设计出基于插件的系统来。如linux 中的totem播放器,基本上什么都不能做,但是,如果你提供mp3的解码器,那么,它就是一个mp3播放器,如果你提供视频解码器,它就成为一个视频播 放器了。*nix下的大部分软件都有这样的特性。 - 尽量标准化
当一个用户比较熟悉*nix系统的命令行程序时,在遇到一个新的程序时,xxx --version应该如预期般打印出软件版本,而不是别的信息。这种趋势现在在windows中也流行起来了。如果所有的程序都遵循某标准的话,就可以很轻松的将他们整合起来,组装成更为强大,专用的东西。 - 文本化,抽象化
几乎所有的*nix系统下的程序都使用配置文件对应用进行高度的定制,这些配置文件都是一些最简单的,可读的文本,这样作的好处是,配置的分析器容易编 写,逻辑比较简单,应用的框架清晰,定制度高。在*nix中,所有的I/O都被抽象成了文件,如网络,音频/视频硬件,硬盘(真实的文件)等,这样作的好 处是,只需要提供一套标准的API,就可以对这些在某些程度上类似的东西进行统一的操作。
在linux提供的工具包中,通过管道连接,可以很容易的将很多个有专一功能的工具整合成可完成某种特定需求的高级工具。就像搭积木一样。这些思想,如果跟当今流行的面向对象思想 略微对比一下就会发现,简直……*nix就是用C写的面向对象的操作系统。
面向对象中,最重要的一点不是{继承,封装,多态} ,而是分工,即绝对相信别的模块,并向外部提供可以被信任的接口。OO体系中的所有参与者都是Object,它们通过消息进行交互,一个大的任务需要被分解,在各个独立的对象对这些分解过的人物进行计算后,再整合起来。注意这里提到的所有参与计算的Object的关系都是平等的,即使是入口处的调度者,也并不必某个字符串分析类更高级。
一个好的设计,每个类之做一件事(只有这样,才可能将其做好),每个类都应该保持相当的简单。而且尽量对调用者不做任何假设(即调用者可能以千奇百怪的方式使用你提供的类)。
在设计的初期,框架尽量是通用的,具体应用无关的,在一个设计的后期才可能涉及到具体的计算,比如linux中的totem播放器框架。
面向对象通过消息将多个对象协调在一起,完成特定的需求。而*nix提供的是操作系统级别的通信方式:管道!a的输出可以定向到b的输入,如此组成一个类似于过滤器的链,当数据从第一个工具中流入,并从最后一个工具流出时,数据已经完全加工好了。
*nix下的大部分工具可以无缝的连接,而这个特点正是由于这些工具之间毫无关系。有一个关于emacs编辑器的笑话:emacs环境太强大了,简直就是一个小型的操作系统,唯一的遗憾是没有一个像样的编辑器。emacs虽然经常会做为没有很好的体现分工,降低耦合等的反面教材提出,但是其中的核心系统+插件 的构架仍然是需要认真学习的。