查看: 902| 回复: 0
跳转到指定楼层
上一主题 下一主题
收起左侧

[学习资料] 设计心法:来自unix的编程哲学

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
有一本书叫做《unix 编程艺术》,在不同的时期分别读了 3 遍,堪称经典中的经典

UNIX 设计哲学

不懂 Unix 的人注定最终还要重复发明一个撇脚的 Unix。--Henry Spenncer, 1987.11

“工程和设计的每个分支都有自己的技术文化。在大多数工程领域中,就一个专业人员的素养组成来说,有些不成文的行业素养具有与标准手册及教科书同等重要的地位(并且随着专业人员经验的日积月累,这些经验常常会比书本更重要)。资深工程师们在工作中会积累大量的隐性知识,他们用类似禅宗'教外别传'的方式,通过言传身教传授给后辈。软件工程算是此规则的一个例外:技术变革如此之快,软件环境日新月异,软件技术文化暂如朝露。

然而,例外之中也有例外。确有极少数软件技术被证明经久耐用,足以演进为强势的技术文化、有鲜明特色的艺术和世代相传的设计哲学。“

Keep It Simple Stuped!

KISS 原则,大家应该是如雷贯耳了。什么是 Simple?简单?golang 语言主要设计者之一的 Rob Pike 说'大道至简',这个'简'和简单是一个意思么?简单不是面对一个问题,我们印入眼帘第一映像的解法为简单。把一个事情做出来容易,把事情用最简单有效的方法做出来,是一个很难的事情。

大家常常因为"自己听说过、知道某个道理"而产生一种心安,认为"我懂了这个道理",但是自己却不能在实践中做到。知易行难,知道却做不到,在工程实践里,就和'不懂这个道理'没有任何区别

给出17条原则的列表,有一些原则看起来有些相似,还有一些原则是相互联系的,在后续解释中具体说明。

  • 模块原则,Modularity:写简单的程序,并用好的接口连接它们
  • 清晰原则,Clarity:清楚透明的算法比“高明”的算法更好
  • 组装原则,Composition:写能够跟其他程序一起工作的程序
  • 隔离原则,Separation:分离接口(使用引擎的方法)和引擎
  • 简单原则,Simplicity:尽量简化算法,不到必要的时候不要增加复杂度
  • 简约原则,Parsimony:只要在必要的时候才写大型程序,通常小程序已经足够了
  • 透明原则,Transparency:写容易测试和纠错的代码
  • 健壮原则,Robustness:这是简单和简约的副产物
  • 表达原则,Representation:用数据结构表达逻辑,而不是用过程表达逻辑
  • 传统原则,Least Surprise:用最常识的方法设计借口
  • 安静原则,Silence:如果程序没什么特别事情要表达,应该保持安静!
  • 经济原则,Economy:程序员的时间比机器的时间更加宝贵
  • 生成原则,Generation:尽量写代码来生成代码,而不是手工输入代码
  • 修复原则,Repair:当程序出现异常,应该明确的抛出异常,而且约早越好!
  • 优化原则,Optimization:先让程序工作,在考虑优化的事情
  • 多样性原则,Diversity:一个问题有很多好的解决方案,没有最好的解决方案!
  • 拓展性原则,Extensible: 设计程序时应该考虑到未来的拓展,因为未来比你想象来的早


1、模块原则:写简单的程序,并用好的接口连接它们
编程的核心是控制复杂度。Brian Kernighan
开发一个项目的绝大部分时间都用来Debug了,所以完成一个项目更多是因为能够控制好Debug的时间和复杂程度。只有一种办法可以有效的控制复杂度:作出简单的子系统,然后用精心设计的接口把他们连接成一个应用。

2、清晰原则:清楚透明的算法比“高明”的算法更好
维护系统的成本非常高,在写程序的时候就应该首先注意程序的可读性,而不是效率。因为,归根结底这些程序是留给其他程序员或者开发者本身阅读的。

实践这个原则包括:良好的注释,简单明了的算法。注释的功能容易理解,简单明了的算法则是因为通常简单的算法更加容易维护且不容易出问题。所以,在性能允许的情况下,尽量选择简单易懂的算法。

永远不要超过三次靠努力思考才能看懂一段代码。第一次可能是侥幸看懂了,但是如果你发现过了一段时间你又需要重新思考一遍才能看懂这段代码,因为你忘了上一次是怎么想的了,这时候你应该注释掉这段代码,这样你就不会第三次为了这段代码发愁了。
3、组装原则,Composition:写能够跟其他程序一起工作的程序
如果你写的代码不能够互相交流,不能相互组合,那么你的代码很快就会成长成一个难以维护的巨大怪物。因此Unix的编程传统鼓励写输入、输出基于文本的程序,很多Unix程序其实就是一个简单的Filter,输入一串字符,输入另一串字符。

从实践的角度,在我们写程序的时候尽量使用简单的字符作为接口,而不是复杂的二进制文件,甚至GUI。

4、隔离原则,Separation:分离接口(使用引擎的方法)和引擎
前后端的分离是一个很好的例子。

5、简单原则,Simplicity:尽量简化算法,不到必要的时候不要增加复杂度
Unix的工程实践形成了这样一种文化:更加欢迎简单的解法,更加注重把系统分解成小的部分。

6、简约原则,Parsimony:只要在必要的时候才写大型程序,通常小程序已经足够
如果程序变得越来越大,就会渐渐失去可维护性。

7、透明原则,Transparency:写容易测试和纠错的代码
写出“透明”的程序至少需要如下两个特性:程序非常直观容易理解;程序有清晰的内部状态并且可以打印,比如日志。

写出“透明”的应用需要在上面的基础上,增加一个特性:使用简单的接口。

8、健壮原则,Robustness:这是简单和简约的副产物
9、表达原则,Representation:用数据结构表达逻辑,而不是用过程表达逻辑
即使是简单的描述过程的语句,对于人来说仍然需要花费很多精力去理解。相反的,即使是复杂的数据结构,人也可以快速的理解。在编程的背景下,数据结构比指令更容易被人理解,也就更容易维护。因此,在编写程序的过程中,应该尽可能的把过程逻辑写入数据结构中。

10、传统原则,Least Surprise:用最常识的方法设计借口
尽量按照业内习惯书写程序,写成程序的时候,就像写书一样,应该时刻想着以后阅读你程序的人(有可能就是未来的你自己),尽可能让他们更加容易的理解你写的程序。

11、安静原则,Silence:如果程序没什么特别事情要表达,应该保持安静!
参考透明原则,不能过度的输出信息,扰乱用户!!

12、经济原则,Economy:程序员的时间比机器的时间更加宝贵
选用一个表达更强、但是慢的语言,很好!节约程序员的时间,浪费机器的时间很划算!而且,更好的编译器可以迅速的提高运行速度。

13、生成原则,Generation:尽量写代码来生成代码,而不是手工输入代码
人,太容易写错了。。。。

14、修复原则,Repair:当程序出现异常,应该明确的抛出异常,而且约早越好!
15、优化原则,Optimization:先让程序工作,在考虑优化的事情
不要过早的开始优化程序,应该快速实现原型

16、多样性原则,Diversity:一个问题有很多好的解决方案,没有最好的解决方案!
不要纠结最好的方案,因为没有!!

17、拓展性原则,Extensible: 设计程序时应该考虑到未来的拓展,因为未来比你想象来的早
特别是设计接口的时候。

应用
如何应用这些原则呢:

  • 数据流应尽可能是文本的(以便可以使用标准工具进行查看和过滤)
  • 数据库布局和应用程序协议应该尽可能是文本的(人类可读和可编辑的)
  • 复杂的前端(用户界面)应与复杂的后端完全分开
  • 尽可能在编写C语言程序之前,使用解释性语言进行原型设计
  • 当且仅当仅使用一种语言可能会使程序过于复杂时,混合语言才比用一种语言编写所有内容更好
  • 更多输入,更少输出
  • 进行过滤时,切勿丢弃不需要的信息
  • 小就是美丽


参考资料

Basics of the Unix Philosophy
http://www.catb.org/~esr/writings/taoup/html/ch01s06.html

评分

参与人数 1大米 +1 收起 理由
14417335 + 1 给你点个赞!

查看全部评分


上一篇:不同语言的代码规范,code review必备
下一篇:系统设计必读DDIA 中文开源版
您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表