2011-01-04 19:44:00 Rainssa 阅读数 1029

随着写的代码越来越多,最近发现《Unix编程艺术》真是本好书。只看了开头部分所归纳的原则,感觉其每一个都非常经典。参照自己过去写代码的经验,只能感叹如果当初早点看到这本书的原则,自己编程的时候能遵从这些原则的话肯定是会少走很多弯路的。

 

先记录经典原则:

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

其中表示原则很有意思,可以广泛应用于3D游戏引擎,因为在优化3D引擎优化方案中,一种是直接用代码优化,另外的是用相关数学推导相应的公式,然后根据已经推导的公式写代码,根据表示原则把知识叠入数据以求逻辑质朴而健壮。所以应该优先考虑后面所述方案。因为推导数学公式不易出错,只要严格遵从数学定理就可以了,根据推导的数学模型公式写代码,这样的代码才健壮。否则的话,直接在代码层面优化,其含义晦涩又容易出BUG。典型的例子就是四元数压缩,在3D游戏中,一个很耗费GPU的就是人物模型动画,我们实现动画都用“骨骼蒙皮”实现。当人运动的时候,关键的骨骼节点变化主要是旋转变化,现在市面上一些教程和程序实现骨骼运动是用简单的旋转矩阵解决问题。如果用旋转矩阵会占用大量的内存且有很多冗余数据。这时候用四元数处理旋转非常好,因为只有4个数(矩阵9个数据),而且可以方便用四元数线性差值。虽然四元数比矩阵少很多数据,还可以对其进行压缩,即把4个浮点类型的四元数压缩为一个32位的整数。例如把一个四元数xyzw 4个浮点类型的数据压缩为一个32位整数的时候,可以用3位表示 x y z 的正负符号。把四元数集合转化为分布在球心在原点的一个球面上。用38种状态判断四元数在哪一卦象解决符号问题的同时,这样只要知道1/8个球面的四元数就可以了。即把四元数集合平均分布映射到1/8球面上,在这1/8球面上平均分布512行和512列点集,其行号和列号分别表示类似于地球表面的纬度和经度。这样四元数表示的角度可以精确到 90/512约为0.175度角,这样角度的精度还是蛮可观的。然后可以行与列的512个数字分别用9位存储转化。这就分配了3+9+9位,剩余的11位全部分配给四元数 W.

例如地球的北极到赤道用512条分布均匀纬线(行号)row表示,当row0表示在北极,当row511表示在赤道位置。如果把笛卡尔坐标轴的Y轴作为地球的自转旋转轴。

 

在这个数学模型中因为: 纬度角/90 = row / 512

 

所以:

row = atan( x / y ) * 512 / 90;

进步优化:row = atan( x/y ) * 0.175781f;

 

 

当然如果是用CPU做简单优化,可以先分配一组内存存储预先计算好的其正弦余弦或正切余切的值,哪个用得多就用哪个。然后代替上式的atan( x/y ),这样直接访问内存的方法就可以去掉反三角函数的计算。在这里用反正切函数纯属为了方便直观表述。

 

以上的简单思路就是先建立推导优化数学模型公式,然后再根据推导出来的数学公式写代码,遵从了表示原则,即把知识叠入数据以求逻辑质朴而健壮。

 

上述罗列的编程原则还是要具体情况具体分析决定。例如我们在写工具的时候就可以遵从经济原则,宁花机器一分,不花程序员一秒。而在一些程序的核心部分追求性能则该忽略它。

 

在《C语言程序设计_现代方法(2)》一书中讲解C语言都还算详细,只是作者谈到C语言不足的时候,作者语气居然抱怨 C语言不能像C++那样写抽象类操作的函数,这点很不好,因为C是面向过程语言,偶尔借鉴C++面向对象思想无可厚非,但总是想把C模拟出C++那样真的很糟糕,之前有段时间是很有热情写C++代码,但到后来用起来感觉蹩脚,而且要改动C++代码是比较难的,应该是由其机制所决定的吧,不像C那样,如果整体设计好的话,到时改变局部对软件全局影响较少,在设计模块的时候,正如《Unix编程艺术》所说,C是属于薄粘合层的,而C++或面向对象语言属于浓厚的粘合层的,所以单凭这点,就觉得CC++好很多。

 

其实从《Unix编程艺术》编程原则可以挖掘深究的东西还有很多,以后有时间再继续

 

2007-08-29 15:22:00 jq0123 阅读数 1503
Unix编程哲学

参考其它另外三个不同版本的翻译:
* Imperfect C++中文版
* 心开天籁
* Unix编程哲学


1.Rule of Modularity: Write simple parts connected by clean interfaces.

模块化准则:编写简单的模块,并用清晰的接口连接它们。

2.Rule of Clarity:Clarity is better than cleverness.

清晰性准则:清晰胜于机巧。

3.Rule of Composition: Design programs to be connected to other programs.

组合准则:设计可以相互连接的程序。

4.Rule of Separation:Separate policy form mechanism; separate interfaces from engines.

分离准则:策略同机制分离;接口同引擎分离

5.Rule of Simplicity: Design for simplicity; add complexity only where you must.

简单性准则:设计要简单,必要时才添加复杂性。

6:Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.

吝啬准则:除非确无它法,不要编写庞大的程序。

7:Rule of Transparency: Design for visibility to make inspection and debug going easier.

透明性准则:设计要直白,使检查和调试更易容。

8:Rules of Robustness:Robustness is the child of transparency and simplicity.

健壮性准则:健壮性源自于透明性与简单性。

9:Rule of Representation:Fold knowledge into data so program logic can be stupid and robust.

表示准则:数据体现知识,让逻辑单纯而健壮

10:Rule of  Least Surprise:In interface design, always do the least surprising thing.

最小惊奇准则:在接口设计中,避免出乎意料。

11:Rule of Silence: When a program has nothing surprising to say, it should say nothing.

沉默准则:如果程序没有什么好说的,就应该保持沉默。

12:Rule of Repair:When you must fail, fail nosily and as soon as possible.

修复准则:如果注定失败,要尽早,要大声。

13:Rule of Economy:Programmer time is expensive; conserve it in preference to machine time.

经济性准则:和机器的时间比较,程序员的时间是更宝贵的。

14:Rule of Generation:Avoid hand-hacking, write programs to write programs when you can.

生成准则:避免手工编程,如果可能,编写程序去生成程序。

15:Rule of Optimization:Prototype before polishing. Get it working before you optimize it.

优化准则:打磨前先成型,优化前先使它工作。

16:Rule of Diversity:Distrust all claims for "one true way".

多样性准则:不相信“唯一正途”。

17:Rule of Extensibility:Design for the future, because it will be here sooner than you think.

扩展性准则:为未来设计,因为它来的比你想得早。

(转载请注明来源于金庆的专栏)
2019-07-21 12:07:00 chunyusi1569 阅读数 3

写在前面

这应该是大学期间读的第一本操作系统方面的书,刚开始接触编程时觉得搞操作系统才是最牛X的,所以和同学一起去图书馆找书,出来各种Windows操作图书,就找到一般Unix编程哲学感觉可以作为小说看看。

Unix编程哲学

关于Unix编程哲学相信大家或多或少多个角度都了解或听到过一些。

比如Kiss:keep it simple, stupid

"简单原则"----尽量用简单的方法解决问题----是"Unix哲学"的根本原则,也是被更多人认可的,以至于在设计模式这种微观角度或者应用架构涉及这种宏观角度,Kiss依然是最被遵守和依赖的原则,比如面对复杂应用场景设计而采用的DDD模式,根本上也是通过结构分割和再组织实现的kiss的目的。

遵守Kiss的好处是:

  1. 清晰原则。

代码要写得尽量清晰,避免晦涩难懂。清晰的代码不容易崩溃,而且容易理解和维护。重视注释。不为了性能的一丁点提升,而大幅增加技术的复杂性,因为复杂的技术会使得日后的阅读和维护更加艰难。

  1. 模块原则。

每个程序只做一件事,不要试图在单个程序中完成多个任务。在程序的内部,面向用户的界面(前端)应该与运算机制(后端)分离,因为前端的变化往往快于后端。

  1. 组合原则。

不同的程序之间通过接口相连。接口之间用文本格式进行通信,因为文本格式是最容易处理、最通用的格式。这就意味着尽量不要使用二进制数据进行通信,不要把二进制内容作为输出和输入。

  1. 优化原则。

在功能实现之前,不要考虑对它优化。最重要的是让一切先能够运行,其次才是效率。"先求运行,再求正确,最后求快。"(Make it run, then make it right, then make it fast.)90%的功能现在能实现,比100%的功能永远实现不了强。先做出原型,然后找出哪些功能不必实现,那些不用写的代码显然无需优化。目前,最强大的优化工具恐怕是Delete键。

转载于:https://my.oschina.net/u/1000241/blog/3076897

2011-03-02 23:06:00 shendl 阅读数 2676

 

      Unix编程哲学:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

另外:

一个程序只做一件事情,并做好。

程序要能协作。

程序要能处理文本流,因为这是最通用的接口。


      
来自《Unix编程艺术》一书。这些原则在很多软件工程,设计模式,敏捷开发书籍中都有提到。    

 

      有时因为设计问题受到同事的挑战。解释起来又挺麻烦的,不是三言两语能说明白的。 以后就把这些原则背出来,再遇到挑战就说是根据**原则设计的,如果不清楚看《Unix编程艺术》这本书或者敏捷开发的书,省得解释了。

 

      一些人喜欢使用二进制协议,觉得文本协议太浪费资源。其实文本协议浪费不多(xml格式除外),能处理的程序多,纠错能力强。最主要的是便于人查看和编辑。

 

     一些人为了提高机器执行效率,到处要求优化。其实很多是废的。甚至因为引入了bug起发作用。至少使代码更难理解。应该优化经测试真正的瓶颈,而不是想当然。

 

     一些人喜欢用一个巨大的程序完成任务,而不是多个小程序。因为觉得线程间交互简单;而进程间交互复杂,而且要使用进程间通讯,效率低。多个小程序的好处是,提供了机制而不是策略。便于重用,具有更大的灵活性,能够满足多种需要。

 

      而且能够积累不少可重用的工具,提高日后的开发效率。 有些公司办了很多年,一点积累都没有,每次来项目都要从头开始写。

     

     如果不愿意或者不能分成多个小程序,至少也应该提供serviceGUI层的逻辑上的隔离。这样service层等模块可以打包成动态链接库,jar包等,便于重用。  

 

     这样,至少如果有一天你的Web程序要提供openAPI(现在很流行)时,不需要大动干戈,重写很多代码。

 

      另外,Linux等开源代码,之所以质量优秀,就是充分的源代码公开和源代码review。 建议公司在项目内形成开诚布公的源代码review风气,改善代码质量。当然这个在一些公司政治严重的团队很难实现。在程序员间容易产生矛盾。


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

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } A:link { so-language: zxx } -->

     一些工程师,喜欢瀑布式的开发方式。一上来设计文档写个几个月,未来描绘得非常美好。代码一行未动。

      项目最后是一延再延,最后发现架构设计有根本性的问题,BUG修复很难,项目只能取消,或者彻底重写。

 

      没有深入到问题内部,和它近距离接触,是很难在脑子中凭空想清楚整个技术方案的。


      我喜欢先设计原型,搭起架子,找到有风险的技术问题,先予以解决。和问题近身肉搏,然后调整、重构,得到可工作的原型,同时也得到了设计方案。再一步步实施。

      

      我很奇怪,一些工程师对问题还没想透,技术风险还没排除,就敢直接花大量的时间写详尽的设计方案!

      如果是概要性质的,还可以理解,毕竟项目总体的设计不会有太大的改变。


 

 


 

    

   

 

 

 

 

 

 

 

 

 

2017-08-04 14:24:11 u012006886 阅读数 209

http://blog.chinaunix.net/uid-253939-id-2458682.html

 

  1. Rule of Modularity: Write simple parts connected by clean interfaces.

  2. Rule of Clarity: Clarity is better than cleverness.

  3. Rule of Composition: Design programs to be connected to other programs.

  4. Rule of Separation: Separate policy from mechanism; separate interfaces from engines.

  5. Rule of Simplicity: Design for simplicity; add complexity only where you must.

  6. Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.

  7. Rule of Transparency: Design for visibility to make inspection and debugging easier.

  8. Rule of Robustness: Robustness is the child of transparency and simplicity.

  9. Rule of Representation: Fold knowledge into data so program logic can be stupid and robust.

  10. Rule of Least Surprise: In interface design, always do the least surprising thing.

  11. Rule of Silence: When a program has nothing surprising to say, it should say nothing.

  12. Rule of Repair: When you must fail, fail noisily and as soon as possible.

  13. Rule of Economy: Programmer time is expensive; conserve it in preference to machine time.

  14. Rule of Generation: Avoid hand-hacking; write programs to write programs when you can.

  15. Rule of Optimization: Prototype before polishing. Get it working before you optimize it.

  16. Rule of Diversity: Distrust all claims for "one true way".

  17. Rule of Extensibility: Design for the future, because it will be here sooner than you think.

    摘自< Art of Unix Programming>

基本Unix哲学

“Unix哲学”起源于Ken Thompson在早期关于如何设计一个小型但是有用而且服务接口清晰的操作系统的思考。随着人们对如何使得Thompson设计发挥最大效力的学习,Unix文化随之诞生并成长,并从各种途径汲取养份。
Unix哲学并不是一个形式化的设计方法。它从不在理论上宣称可以生产出更好的软件。也不能妄想指望它在一个很短的期限里使用糟糕的项目管理和廉价程序员做出一个极俱创新而又可以信赖的软件。
Unix哲学(以及其它领域内被认为是成功的“民间”传统)是自下而上的,而非相反。它注重实效并且基于经验。你不能在正式的方法和标准中找到它们,它们属于隐性、反身性知识。
Doug McIlroyUnix管道的发明者也是Unix传统的奠基人之一,说
(i)让每一个程序只很好得做一件事情。当出现新工作的时候应该重组已有的程序而不是通过添加新特性使得原有程序变得复杂。
(ii)每个程序的输出应该可以成为另一个程序的输入,甚至一个未知程序。不让让彼此无关的消息混乱你的输出。尽量避免二进制输入格式。不要强求交互式输入方式。
(iii)设计和建造软件,包括操作系统,应尽早规划好。对于拙劣的部分不要犹豫不决,扔掉并重写它们。
(iv)使用工具可以减轻编程负担,即使你可能决定这些工具在建造后只使用几次。
他后来又这样总结:This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
Rob Pike,一位伟大的C语言大师,从一个略微不同的角度给出了一些C编程的注解:
规则1你无法预料一个程序在何处花费时间。瓶颈常会发生在出人意料的地方,所以在你能证明瓶颈所在之前,不要做第二次无谓的猜想。
规则2测量。在你测量之前不要盲目追求速度,除非某个部分的代码淹没了其它的。
规则3在n很小的时候,一个新异的算法会很慢,而且通常n不会很大。这些算法会有很大的常数。除非你确信n会很大,否则不要使用。  (即使n很大,也先适用规则2)
规则4新异的算法要比简单算法大得多,并且很难实现。尽量使用简单得算法和简单得数据结构。
规则5数据支配。如果你准确选择了数据结构并正确组织它们,那么算法很可能已经自动构筑完成。数据结构,而不是算法是编程的重点。
规则6没有其它规则。

Ken ThompsonUnix得设计和缔造者之一,用了禅宗里得一句话进一步描述了上面得规则4:
When in doubt,use brute force(告诉我谁把佛经翻译成了英语,我去杀了他)
更多得Unix哲学隐含在先哲们的行为以及Unix本身,而不是在先哲们留给我们的话语。纵观全局,我们可以总结出一部分思想:
1 模块化原则:编写简单的组件,用整齐的接口让它们互联。
2 清晰性原则:清晰要比灵巧重要。
3 整合化原则: 新设计的程序要考虑和其它程序共同工作。
4 分离性原则: 让机制与策略分离;让接口同引擎分离。
5 简单化原则: 为了简单而设计;只在你确信必要的地方增加复杂度。
6 吝啬性原则: 只有被证明了其它东西无法完成工作时才编写“大”程序。
7 透明化原则: 设计一个高度可见的程序可以使检查及调试更容易。
8 健壮性原则: 健壮性是透明化以及简单化的产物。
9 Rule of Representation:Fold knowledge into data so program logic can be stupid and robust.
10 最小立异化原则: 在接口设计方面,一定不要总想标新立异。
11 安静性原则: 当一个程序没有什么值得炫耀时,就不要炫耀。
12 修复原则: 是的,一旦当你不得不面对失败时,失败就会变得愈发喧闹。
13 经济性原则: 程序员的时间是宝贵的,把它让度于机器时间。
14 生产化原则: 避免手工hacking操作;尽可能让程序完成编程工作。
15 优化性原则: 先做模具再打磨润色;先让程序工作,然后优化它。
16 多样化原则: 千万不要信赖包治百病的药。
17 控制性原则: 多为将来考虑,因为它会比你预料更快地来到现实。

如果Unix对你还是陌生地,这些原则值得你去沉思。软件工程的教科书会也向你夸耀这里的多数原则;但是大多数操作系统缺少好的工具和传统,所以这些平台上的程序员根本无法应用它们。这些程序员不得不接受生硬的工具,坏的设计,疲劳工作以及过度膨胀的代码,甚至习以为常(他们甚至不知道Unix爱好者为什么如厌恶他们的工作和习惯)。

模块化原则:编写简单的组件,用整齐的接口让它们互联。
Brian Kernighan曾经总结说,“ 复杂度控制是计算机编程最重要的事情。 ”测试(debugging)决定了整个开发时间。好的方法可以事半功倍。
汇编器,编译器,流程图,结构化编程,“人工智能”,第四代语言(译者注:指各类*nix脚本语言),面向对象,以及不计其数的软件工程方法都试图并宣称解决这个问题,而然只要提升程序的复杂度,这些方法依然会因为人脑的限制而失败,在Fred Brooks看来,不存在“银弹”。
构筑一个复杂软件的唯一途径就是降整体的复杂性分担到一个个通过良好定义的接口互联的简单模块,多数问题是局域性的,这样完全可以修改出问题的模块而不破坏整体。

清晰性原则
:清晰要比灵巧重要
软件的维护是重要的并且昂贵的,写出的程序并是仅仅给执行它的计算机处理,更重要的是要给你的人类朋友看,给那些将来维护软件的人看(这其中也包括你自己)。
Unix传统中,注释你的代码只是一部分。好的Unix方法同样会注重于你的算法和实现是否有利于将来的维护。为了一点点儿性能上的优势,而增加大量的复杂性是一桩糟糕的买卖。复杂的代码容易窝赃bug,更会让维护人员头疼。
优雅而简洁的代码,不易破裂且让修改者很容易维护。这点非常重要,特别是当这个维护者是几年后的你。
不要试图阅读那些复杂的代码超过三次。一次就读懂或许是侥幸,如果你发现很长一段时间后必须再次看它,而你已经忘记了细节。是时候为它编写注释了,这会让你第三次阅读时轻松很多。

-- Henry Spencer

整合化原则: 新设计的程序要考虑和其它程序共同工作
如果你编写的程序彼此间不能通讯,那么将无法避免过度的复杂性。Unix传统强烈期望程序可以读、写简单的、基于文本和流式以及设备无关的格式。经典的Unix中,有大量的程序作为过滤器(filter)出现,过滤器从一个程序获得文本输入处理后再将文本输出。
出现这一情况并不是Unix程序员都不喜欢图形用户界面。而是因为如果不用字符流,程序间很难挂钩。
字符流作为消息传递的Unix工具是面向对象的。

一句话Unix哲学

所有这些这些哲学其实可以浓缩成一个被专家工程师奉为经典的法则:
KISS 法则
KISS
 的全写是KISS Is Simple,Stupid(或者Keep It Simple, Stupid)
Unix能够给你提供一个极好的平台应用KISS法则。本书的余下部分会帮助你学习如何应用。

应用Unix哲学

这些哲学原则绝不是含糊的概念。在Unix世界,它们直接源于经验,并指导我们正在从事的具体开发实践。这里有一份可能尚不完全的表:

* 任何与源代码、目标无关的过滤器都要有一个。
* 数据流只要可能就应该是文本的(这样才可以用标准的工具阅读和过滤)
* 数据库规划和应用协议只要可能应该是文本的(文本可读、文本可编辑)
* 复杂的前端(用户界面)和负责的后端之间应该被清晰分离
* 如果可能,在决定用C语言编码前尝试解释性语言(译者注:包括脚本语言)
* 使用多种语言要比单一的语言好,除非这这会增加复杂性
* 更多得接受各种输入,对于输出则要吝啬的控制
* 过滤时不要丢掉你可能并不需要的信息
* 小就是好的,写程序时做到刚好能够完成你的任务

我们将会观察Unix设计规则以及从这些规则中导出的原则,并应用它们。就像预料中的,它们正成为其它领域内软件工程里最好的原则。

态度决定一切

当你面对正确的选择,去做它——在一个短期计划中,经常会是这样,而然在一个长期的计划中这也许并不能取得什么效果。如果你还不能确定到底改作什么,那么就做能让工作完成的最少的事情,至少在你确定真正正确的事情前。

正确地应用Unix哲学,需要你的忠诚。你必须绝对相信软件开发是一个要动用你所有智慧、创造力和激情的活计。此外你不能指望简单的套用过去方法实现现在的设计;你必须在你应该思考的地方进行新的编码。你会在不经意间使得本该简单的实现复杂化-接着你会疑问并抱怨为什么你的代码会迅速膨胀并难以调试。

正确地应用Unix哲学,充分利用你的所有时间不要浪费。如果某个人已经针对某个问题做出了好的解决方案,不要因为好面子而进行无意义的重复工作。不要做出比预计更复杂的设计,让设计轻巧更重要。用你的工具,让可能的事情自动化。

软件开发应该是一个令人愉乐的艺术,一个高级的游戏。如果你不同意这个看法,停下手边的工作,问问自己遗忘了什么?为什么你做软件开发而不是去挣更多的钱或者空耗时间?你必须将软件作为一件燃烧你激情的事情。

正确地应用Unix哲学,你需要接受这个态度。你需要维护它,需要去游戏,需要有探索的意愿。
我们希望你带着这个态度去阅读本书。或者至少希望本书能帮助你建立其这种态度。
没有更多推荐了,返回首页