目录
14、生成原则:避免手工hack,尽量编写程序去生成 程序。
总结:一言以蔽之,就是K.I.S.S —— keep it simple,stupid !
本文只是《Unix编程艺术》的搬运工,增加了一点点个人的理解,哲学就是知识的升华,玄学,让你觉得很牛逼,但是用的时候,又很难想到,所以只是作为拷贝。
阐述一:
(1) 让每个程序就 做好一件事儿,如果有新人物,就重新开始,不要往原程序中加入新功能而搞得复杂。(模块化设计)
(2)假定每个程序的输出都会成为另一个程序的 输入,哪怕那个程序还是 未知的,输出中不要有无关的信息干扰,避免使用严格的分栏格式和二进制格式输入,不要坚持使用交互输入。
(3)尽可能早地将设计和编译的软件投入使用,对拙劣的代码别犹豫,扔掉重写。(拙劣的代码,先天就缺陷,所以不如再造一个)
(4)有限使用工具,而不是拙劣的 帮助来减轻编程任务的负担,工欲善其事,必先利其器。(不要重复造轮子,要多用别人做好的轮子,即便自己造轮子,可能也不如别人造的好,了解别人造轮子的过程细节即可)。
阐述二
(1)你无法 断定程序会在什么地方耗费运行时间,瓶颈经常出现在 想不到的地方,所以别急于路乱找个地方 改代码。
(2)估量,在你没有对代码进行估量,特别是没有找到最耗时的那部分 之前,别去优化速度。
(3)花哨的算法在n 很小的时候通常很慢,而n通常 很小,花哨算法的常数复杂度很大,除非你确定n总是很大,否则不要用花哨的算法(即使n很大,也有限考虑原则2)。
(4)花哨的算法比简单的算法更容易出bug,更 难实现。尽量使用简单的算法配合简单的数据结构(拿不准就穷举)
(5)数据压倒一切,如果已经选择了正确的数据结构,并且把一切都组织的井井有条,正确的算法那也就不言自明了。编程的核心是数据结构, 而不是算法。(数据结构本身就反映了编程逻辑和算法)。
阐述三:
1、模块原则。
使用简洁的接口拼合简单的部件。排错会占用大部分的开发时间,弄出一个拿得出手的可用系统,与其说出自才华横溢的设计成果,还不如说是跌跌撞撞的结果。要编制复杂的软件而又不至于一败涂地的唯一方法就是降低其整体复杂度,用清晰的 接口把若干简单的模块组合成一个复杂的软件, 如此一来,多数问题只会局限于某个局部,那么就还有希望对局部进行改进而不至于牵动全身。
2、清晰原则。
清晰胜于机巧。程序不仅仅是给CPU看的,更是为维护人员,尤其是自己看的。因为程序不是一锤子买卖,需要持续不断的升级优化。所以不仅要有详细的注释。同样在选择算法和实现时就应该考虑将来的可扩展性,为了取得程序一丁点的性能提升就大幅度增加技术的复杂度和晦涩性,是不值得的。
3、组合原则.
设计时考虑拼接组合,输入输出方面,Unix极力提倡采用简单、文本化、面向流、设备无关的格式。多数程序都尽可能采用将一个输入的简单文本流处理为一个简单的文本流输出。
4、分离原则:策略同机制分离,接口同引擎分离。
Unix只提供机制,也就是说提供的工具有n多种,比如shell命令的 参数项 特别多,让人眼花缭乱,但是unix并不主动去支持UI界面操作,因为 这些所谓的界面操作,都是策略,策略交给用户,用户的需求才是 他最想要的,不去尝试着硬给用户,这一点跟 苹果 的设计理念相悖,这也是因为乔老爷子是天才,他比我们自己都熟悉我们喜欢的体验。
5、简洁原则:设计要简洁,复杂度能低则低。
来自多方面的压力通常会让程序变得复杂(由此代价更高,bug更多),其中一种压力就是来自技术上的虚荣心理,程序员们都很聪明,常常以能够玩转负责东西和耍弄抽象概念的能力为傲,但是正是如此,他们的设计能力大大超出了他们的实现和排错能力,结果便是代价高昂的废品。Unix的程序员相互比的谁能够做到“简洁而漂亮”并以此为荣。
很多商业软件,过度的复杂性虽然来自于项目的需求,但是常用的功能只占全部功能的5%,复杂功能更多的是为了推销,所以尽可能的设计要简洁,支持刚需,奇葩的需求少做,因为程序越臃肿,bug越多。
6、吝啬原则:除非确无 它法,不要编写庞大的程序。
程序越大,维护起来越复杂,需要花费大量的经历,也让人难以割舍,结果导致庞大的资源投入,注定成功率低。
7、透明性原则:设计要可见,以便 审查和调试。
调试至少要占用四分之三的开发时间,所以在设计的时候,尽可能的保持透明,方便后续调试。透明性是指你一眼就能看出软件在做什么以及怎么做的。
8、健壮原则:健壮源于透明与简洁。
多数软件禁不起磕碰,毛病多,就是因为过于复杂,很难通盘考虑,如果不能够正确理解一个程序的逻辑,就不能确信其是否正确,也就不能在出错的时候修复它。所以我们想要程序健壮,就需要程序内部的逻辑更易于理解,要透明、简洁。
这一点以freemodbus 举例,这个程序是非常健壮的,健壮并不是因为作者的想法多奇妙,而是因为作者将 mobus通信 的流程做了足够的细化和拆分,从串口接收中断、发送中断、定时器中断、详细的状态机、modbus协议层等等,做了足够细的 分层,而且每层之间都是耦合的,最重要的是因为做了足够细化,所以每个模块设计的都比较透明和简洁,所以整个程序运行的非常健壮。
千万不要觉得程序是自己写的,我们就 对程序的所有细节都清楚,要知道人的大脑不是硬盘,会忘记的,所以我们 在设计的时候,就要尽可能的将程序架构设计的透明和简洁。
9、表示原则。
把知识叠入数据以求逻辑质朴而健壮。
10、通俗原则:接口设计 避免标新立异。
“最少惊喜原则”,不要去 痴迷 机巧和标新立异,要在基本功上,熟能生巧。
11、缄默原则:
如果一个程序没有什么好说的,就沉默。重要的信息不应该混杂在冗长的程序内部行为信息中,没什么 好说的,就别说。这也是为什么 unix的各种 函数,成功返回 0,不成功才会返回各种信息。
12、补救 原则:
出现异常时, 马上退出并给出足够错误信息。这一点不仅仅是各种错误打印,更多的是 要重视各种系统软中断,比如各种 信号,所以我们的程序中要多用 信号 中断函数服务函数,能够应对各种异常情况,起码能够快速的发现问题。
13、 经济原则:宁花机器一分,不花程序员一秒。
有时候浪费一部分机器资源,但是会给整个系统带来更加简洁透明,也更加方便,不要去考虑蝇头小利的效率提升。举一个简单的例子,某个组态软件在创建设备表后,不管这个设备表是读1个寄存器还是512个寄存器,都会给这个设备表分配512个寄存器空间,这样做可能对于 那些读少数寄存器的设备表造成了资源的浪费,但是。。整齐、统一的空间分配无疑会大大提升程序员的效率,而且毕竟读1个寄存器的设备表是少数,所以这就叫 宁花机器一分,不花程序员一秒。
14、生成原则:避免手工hack,尽量编写程序去生成 程序。
人类不擅长干辛苦的细节工作,因此程序中的任何手工hacking都会滋生错误和延误,程序规格越简单,设计者就越容易作对。具体来讲,就是要多用 自动化工具,比如Makefile,现在的工程文件动辄几十个文件,更多的是几千、几十万个文件,如果手动去编译配置,不仅效率低,更多的是容易出bug,所以要充分利用 正规表达式进行自动编译。
15、优化原则: 雕琢前先要有原型,跑之前先学会走。
说的太好了,先有大框架,不要上来就研究技术细节,有框架后,代码就撸起来,代码写多了,问题遇到多了,自然而然的就会优化了。90%的功能现在能实现,比100%的功能永远实现不了强。我们不应该考虑蝇头小利的效率提升,过早的优化是万恶之源。先制作原型,再精雕洗濯,优化之前先确保能用。先求运行,再求正确,最后求快。
所有这些话的实质就是:先给你的设计做个未优化、运行缓慢、很耗内存但是正确的实现(宁花机器一分,不花程序员一秒),然后进行系统调整,寻找那些可以通过牺牲最小的局部简洁性而获得较大性能提升的地方,
16、多样原则:绝不要相信所谓“不二法门”的断言。
再出色的软件也常常会受限于设计者的想象力,毕竟人不是神,没有人能聪明到把所有的东西都最优化,所以不要相信任何所谓的不二法门。
17、扩展原则:设计着眼未来,未来总比预想来得快。
相信别人所宣称的是“不二法门”是不明智的,坚信自己的设计是“不二法门”就是愚蠢的,绝对不要认为自己找到了最终的答案,因此要为数据格式和代码留下扩展空间,否则就会发现自己常常被原来的不明智选择捆住手脚,因为你无法既要改变他们又要维持对原来的兼容性(定框架的时候,不要怕定庞大了,框架先定大,大不了只支持最简单的1种嘛)
总结:一言以蔽之,就是K.I.S.S —— keep it simple,stupid !
转载:https://blog.csdn.net/u012351051/article/details/100638441