Unix哲学(《unix编程艺术》书摘)

来源:互联网 发布:网络版权 编辑:程序博客网 时间:2024/04/29 13:47

Unix哲学

1. 模块原则:使用简洁的借口拼合简单的部件。

要编写复杂的软件又不至于一败涂地的唯一方法就是降低其整体复杂度——用清晰的接口把若干简单的模块组合成一个复杂软件。如此一来,多数问题只会局限于某个局部,那么就还有希望对局部进行改进而不至于牵动全身。

2. 清晰原则:清晰胜于机巧。

维护如此重要而成本如此高昂:在写程序时,要想到你不是写给执行代码的计算机看的,而是给人——将来阅读维护源码的人,包括你自己看的。

3. 组合原则:设计时考虑拼接组合。

在输入输出方面,Unix传统极力提倡采用简单、文本化、面向流、设备无关的格式。
要想让程序具有组合性,就要使程序彼此独立。

4. 分离原则:策略同机制分离,接口同引擎分离。

把策略同机制揉成一团有两个负面影响:一来会使策略变得死板,难以适应用户需求的改变,二来也意味着任何策略的改变都有可能动摇机制。
相反,将两者剥离,就有可能在探索新策略的时候不足以打破机制。另外,我们也可以更容易为机制写出较好的测试(因为策略太短命,不值得花太多时间在上面)。

5. 简洁原则:设计要简洁,复杂度能低就低。

以简洁为美,人人对庞大而复杂的东西群起而攻之。这是一个非常看重解决方案的工程传统,总是设法将程序系统分解为几个能够协作的小部分,并本能地抵制任何用过多噱头来粉饰程序的企图。

6. 吝啬原则:除非确无他法,不要编写庞大的程序。

“大”有两种含义:体积大,复杂程度高。程序大了,维护起来困难。由于人们对花费了大量精力才做出来的东西难以割舍,结果导致庞大的程序中把投资浪费在注定要失败或者并非最佳的方案上。

7. 透明性原则:设计要可见,以便审核和调试。

因为调试同行会占用四分之三甚至更多的开发时间,所以一开始就要多做点工作以减少日后调试的工作量会很划算。一个特别有效地减少工作量的方法就是设计时充分考虑透明性和显见性。 软件系统的透明性是指你一眼就能够看出软件是在做什么以及怎样做的。显见性指程序带有监视和显示内部状态的功能,这样程序不仅能够运行良好,而且还可以看得出它以何种方式运行。

8. 健壮原则:健壮源于透明与简洁。

软件的健壮性指软件不仅能在正常情况下运行良好,而且在超出设计者想的意外条件下也能运行良好。
就健壮性而言,设计时要考虑到能承受极端大量的输入。在有异常输入的情况下,保证软件健壮性的一个相当重要的策略就是避免在代码中出现特例。bug通常隐藏在处理特列的代码以及处理不同特殊情况的交互操作部分代码中。

9. 表示原则:把知识叠入数据以求逻辑质朴而健壮。

数据要比编程逻辑更容易驾驭。所以接下来,如果要在复杂数据和复杂代码中选择一个,宁愿选择前者。更进一步:在设计中,你应该主要将代码的复杂度转移到数据之中去。

10. 通俗原则:接口设计避免标新立异。

接口设计应该避免毫无由来的标新立异和自作聪明。如果你编写一个计算器程序,“+”应该永远表示加法。而设计接口的时候,尽量按照用户最可能熟悉的同样功能和相似应用程序来进行建模。

11. 缄默原则:如果一个程序没什么好说的,就沉默。

若程序没有什么特别之处可讲,就保持沉默。行为良好的程序应该默默工作,决不唠唠叨叨,碍手碍脚。

12. 补救原则:出现异常时,马上退出并且给出足够错误信息。

软件要尽可能从容地应付各种错误输入和自身的运行错误。但是,如果做不到这点,就让程序尽可能以一种容易诊断错误的方式终止。
Postel规定“宽容地收,谨慎地发”:就算输入的数据很不规范,一个设计良好的程序也会尽量领会其中的含义,以尽量与别的程序进行协作;然后,要么响亮地倒塌,要么为工作链下一环的程序输出一个严谨干净正确的数据。

13. 经济原则:宁花机器一分,不花程序员一秒。

如果我们在整个软件开发中很严格遵循这条原则的话,大多数的应用场合都应该使用高一级的语言,如Perl、Tcl、Python、Java——这些语言可以将程序员从自行管理内存的负担中解放出来。
另一个可以显著节约程序员时间的方法是:教会机器如何做更多低层次的编程工作。

14. 生成原则:避免手工hack,尽量编写程序去生成程序。

众所周知,人类很不善于干辛苦的细节工作。因此,程序中的任何手工hacking都是滋生错误和延误的温床。程序规格越简单越抽象,设计者就越容易作对。由程序生成代码几乎(在各个层次)总是比手写代码廉价并且更加值得信赖。
在Unix传统中,人们大量使用代码生成器使易于出错的细节工作自动化。Parser/Lexer生成器就是其中的经典例子,而makefile生成器和GUI界面式的构建器(interface builder)则是新一代的例子。

15. 优化原则:雕琢前先要有原型,跑之前先学会走

90%的功能现在实现,比100%的功能永远实现不了强。做好原型设计可以帮助你避免为蝇头小利而投入过多的时间。另一方面,过早优化是万恶之源。在还不知道瓶颈所在就匆忙进行优化,这可能是唯一一个比乱加功能更损害设计的错误。
“极限编程”宗师Kent Beck从另一种不同的文化将这一点有效地扩展为:先求运行,再求正确,最后求快。

16. 多样原则:绝不相信所谓的“不二法门”的断言

即使最出色的软件也受限于设计者的想象力。没有人能聪明到把所有东西都最优化,也不可能预想到软件所有的用途。设计一个僵化、封闭、不愿意与外界沟通的软件,简直就是一种病态的傲慢。
因此,对于软件设计和实现来说,Unix传统有一点很好,即从不相信任何所谓的“不二法门”。Unix奉行的是广泛采用多种语言、开放的可扩展系统和用户定制机制。

17. 扩展原则:设计着眼未来,未来总比预想来得快

稍微增加一点让数据部署具有自描述性的开销,就可以在无需破坏整体的情况下进行扩展,你得付出也就得到了成千倍的回报。
设计代码时,要有很好的组织,让将来的开发者增加新功能时无需拆毁或者重建整个架构。当然这个原则不是你能随意增加根本用不上的功能,而且建议在编写代码时要考虑到将来的需要。

总结为一条铁律:K.I.S.S(Keep It Simple,Stupid!)

0 0