我觉得一切伟大的设计似乎都是不朽的,例如矗立在雅典卫城石灰岩山岗上的帕特农神庙,米开朗基罗刀工斧凿下充满雄性魅力的大卫,毕达哥拉斯对勾股定理的演绎证明,乱臣贼子亦为之惧怕的孔子春秋大义与君子之道,观苹果坠落而引发思考的牛顿三大定律,门捷列夫探索元素本质进而发现的元素周期表以及冯·诺伊曼定义的计算机硬件体系架构,都是不朽的。这些设计或许在某个时刻已经不再为人所用,或者仅供瞻仰,但其设计的精神却恒久而不废。
大约,Unix的设计哲学亦如此。
Doug McIlroy, Elliot Pinson和Berk Tague总结了两点Unix设计哲学:
一个程序只做一件事情,符合“单一职责原则”,每个程序变得简单。粒度如原子一般精简的小,则可以通过组合完成更为复杂的功能。程序的输入和输出都是统一的,就能统一接口(uniform interface),支持自由的组合,程序之间“老死不相往来”,没有依赖,设计的扩展也就变得游刃有余。
Unix中“管道”的隐喻高度抽象整个输入输出,化之为文件流(Stream),无论是文件系统,还是Unix Socket,设备驱动,内核API,TCP连接,都可以视为流而统一对待。
参与管道的各个独立程序遵循了同样的契约。输入为stdin,输出则视结果而为stdout或stderr。思考架构模式中的“管道过滤器”模式,思考事件驱动架构(EDA),思考Storm或者Spark Streaming对流的处理,思考Scala中Parser的原理,几乎都看到了这一Unix设计哲学的影子。
Martin Kleppmann在文章Apache Kafka, Samza, and the Unix Philosophy of Distributed Data中比较了Unix设计哲学与数据库的设计哲学。
Unix设计哲学将stdin和stdout视为通信通道(communication channel),数据库的设计模式则是服务器/客户端。虽然数据库通过存储过程、trigger、SQL等多种机制为客户端提供了强大的扩展功能,但数据库之间或者其他数据源之间却不能组合起来,例如无法将MySQL的数据通过管道传给ElasticSearch。
Martin Kleppmann认为数据库的设计思想是Self-Centered:
我认为数据库的设计非常以自我为中心(self-centered)。数据库将自己视为宇宙的中心:是你存储和查询数据唯一的栖息之地,乃真理之源,所有查询的目标。
这种设计思想可以总结为“one size fits all”,这与Unix分而治之的设计思想背道而驰。
当我们需要集成不同的数据库时,DB的这种设计就暴露出问题了。每个DB都是一个独立的系统,如果需要集成多个数据库,就像处理“烟囱系统”那般困难,需要专门的集成方式,例如通过ETL对不同格式的数据进行加载、提取和转换。
Unix依旧如服了长生不老药一般继续工作下去,不眠不休。若没有它的设计哲学作指引,它或许已经崩溃、疯狂或者死亡,正如人没有信仰。软件设计需有思想的支持,否则设计的结果没有灵魂。