Unix 编程艺术

文章出处,原创于 https://HawkingOuYang.github.io/

我的GitHub


编程之道

江湖秘诀 by OYXJ on 2016.10.19

iOS 编程之道 :) → 天下武功,唯快不破;编程之道,唯慢不破。

工作的时候:业务 —驱动—> 技术

闲暇的时候:技术 —反哺—> 业务

生活的时候:生活 —提炼—> 业务

休息的时候:时间 —沉淀—> 技术

文武之道,一张一弛;(道)
四季循环,自有天时;(天)
拥抱变化,因地制宜;(地)
就事论事,将心比心;(人)

Coding 是一种训练思维的方式,使用编程语言对现实世界的抽象、描述、实现、改造;

钢琴、医学、心理学、城建 等,都是以各自的语言,去抽象、描述、实现、改造 身边的世界;

从 农村、县城、区、市、省、北京,求是、创新、享美,孩提、少年、成年、壮年、老年、暮年,这个认识链、价值链,需要重构。不慌不忙,慢慢来…… 就像四季的过程一样。

眼界: 不要忙于向外扩张,认识到20多年的经历、变化 与 成长,其实 每个人 都带着宝藏,看你会不会挖掘和使用。

年轻的时候,多学习、反思、积累、沉淀,目的在于:年长之后,领导正如自己现时的年轻人。

At twenty years of age the will reigns; at thirty, the wit; and at forty, the judgment. —- Benjamin Franklin

每个年龄段都有核心竞争力:10岁 家庭环境培养的习惯(habit),20岁 毅力(will),30岁 智慧(wit),40岁 判断(judgment),50岁 视野(vision),60岁 人脉(connection)。

Unix 编程原则 17条

unix设计十七条原则之一(unix编程艺术笔记)

unix设计十七条原则之二(unix编程艺术笔记)

最近在学习《unix编程艺术》。第一章非常不错,讲了很多Unix的历史,哲学基础,其中最重要的是提到的十七条设计原则。很多原则自己也知道,但是从来没有总结的如此详细深刻。
下面的内容大部分来自《unix编程艺术》这本书,少部分是我的一些理解。这是我读书的一个习惯,对于我认为重要的,我会把它打出来,在打字的过程中我会根据深入的思考理解。所以,笔记对我来说是一个思考和记忆的辅助手段。

(1)、模块原则:使用简单的接口拼接简单的部件

“计算机编程的本质就是控制复杂度”。
要编制复杂软件而又不至于一败涂地的唯一的方法就是降低其整体复杂度——用清晰的接口把若干个简单的模块组合成一个复杂的软件。如此一来,多数问题就只会局限于某个局部,那么还有希望对局部进行改进而不至于牵动全身。
注:控制复杂度,我在多个地方都看到过。把整体的结构搭建好后,各个模块也可以独立的演进而相互之间没有影响。

(2)、清晰原则:清晰胜于机巧

程序是给人看的,而不是机器。
这个原则不仅仅是指可读性,同时也指在选择算法和实现时就应该考虑到未来的可扩展性。不要为了提升一丁点的程序的性能就增加技术的复杂性和晦涩性——因为复杂的代码更容易滋生bug,也因为它会使日后的阅读和维护工作更加艰难。
优雅而清晰的代码不仅不容易崩溃——而且更利于后来的修改者立刻理解。

(3)、组合原则:设计时考虑拼接组合

如果程序间不能有效的通信,那么软件就难免会陷入复杂度的泥淖。
Unix传统极力提倡采用简单,文本化,面向流,设备无关的格式。
要想让程序具有组合性,就必须是程序彼此独立。在文本流这一端的程序应该尽可能不要考虑文本流另一端的程序。将一端的程序替换为一个截然不同的程序,而完全不惊扰另一端的程序应该很容易做到。
对于协议的设计,尽量采用简单的文本数据格式。

(4)、分离原则:策略同机制分离,接口同引擎分离

什么是机制:提供的功能;什么是策略:如何使用功能;这两个词有些费解。
策略的变化要远远大于机制的变化。将两者分离,可以使机制相对保持稳定,而同时支持策略的变化。
这条准则在GUI环境之外也被广泛应用。总而言之,这条准则告诉我们要将接口和引擎剥离开来。
“接口和引擎”?又是两个费解的概念。作者列举了两个实例,一个是Emacs,它是用LISP驱动C的程序来实现的——也就是使用内嵌脚本语言驱动c服务程序:C语言编写底层服务(引擎),给脚本语言调用,使用脚本语言实现流程。另一个实例是将应用程序分为协作的前端和后端,前端实现策略,后端实现机制。
可以认为接口就是策略(用户接口),引擎就是机制。
注:代码大全中提到“隔离变化”的概念,以及设计模式中提到的将易变化的部分和不易变化的部分分离也是这个思路。

(5)、简洁原则:设计要简洁,复杂度能低则低

来自多方面的压力使程序变得复杂,其中一种压力就是技术上的虚荣心。程序员都很聪明,常常以玩转复杂的东西和耍弄抽象概念的能力为傲。“看看谁能鼓捣出最错综复杂的美妙事物”:
“听起来自相矛盾,Unix程序员相互比的是谁能够做到“简洁而漂亮”,并以此为荣。
另一个眼里来自软件营销策略:看谁提供更多的功能——这会扼杀优秀的设计。
要鼓励一种文化,以简洁为美,对复杂的东西群起而攻之。

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

大的含义:体积大,复杂度高;
避免编写庞大程序的方法的分割程序。一个程序只做好一件事情。

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

调试占看法的四分之三的时间,一个减少调试工作量的有效的方法就是在设计之初充分的考虑透明性和显见性。
软件系统的透明性是指你一眼就能看出软件在做什么以及怎么做的。显见性是指程序带有监视和显示内部状态的功能。这样的程序不仅能够运行良好,而且还可以看出它以何种方式运行。
设计时如果充分考虑这些,会对项目全过程带来好处。

(8)、健壮原则:健壮源于透明和简洁

软件的健壮性是指软件不仅在正常的情况下运行良好,而且在超出设计者设想的意外条件下也能够运行良好。
大多数软件缺乏健壮性,是因为过于复杂。
获得健壮性的方法:让程序的内部逻辑更易于理解。主要有两种方法:透明化和简洁化。程序越简洁,越透明,也就越健壮。
模块性(代码简朴,接口简洁)是组织程序以达到更简洁目的的一个方法。

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

即使最简单的程序逻辑让人类来验证也很困难,但是就算是很复杂的数据,对人类来说,还是相对容易地就能够推导和建模的。
数据比编程逻辑更容易驾驭。在复杂数据和复杂代码中选择,宁可选择前者。在设计中,你应该主动的将代码的复杂度转移到数据中去。
Rob Pick讲到的第五个原则:
数据压倒一切。如果你已经选择了合适的数据结构并且把一切都组织得井井有条,正确的算法也就不言自明。编程的核心是数据结构,而不是算法。

(10)、 通俗原则:接口设计避免标新立异

也就是众所周知的“最少惊奇原则”。
最易用的程序就是用户学习新东西最少的程序。
另一个方面是避免表象相同而实际却略有不同,这会及其危险。最好让不同事物有明显区别,而不要看起来几乎一模一样。

(11)、 缄默原则:如果一个程序没有什么好说的,就保持沉默

“简洁是Unix的核心风格。重要的数据不应该混杂在冗长的程序内部行为信息中。”

(12)、 补救原则:出现异常时,马上退出并给足异常信息

软件要尽可能从容的应付各种错误输入和自身的运行错误。但是,如果做不到这一点,就让程序尽可能以一种容易诊断错误的方式终止操作。
对于协议:要宽进严出。

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

应该采用更加高级的语言,让程序员从自习管理内存的负担重解放出来。

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

也就是教会机器去做更多低层次的编程工作。
一个方向就是DSL。

(15)、 优化原则:雕琢前先得有原型,跑前先学会走

过早优化时万恶之源,他会损害设计。
先给你的设计做个未优化的,运行缓慢的,很耗内存但是正确的实现,然后向进行系统调整,寻找那些可以牺牲最小的局部的简洁性而获得较大的性能提升的地方。

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

即使最出色的软件也常常会受限于设计者的想象力。
Unix奉行的是广泛采用多种语言、开发的可扩展机制和用户定制机制。

(17)、 扩展原则:设计着眼未来,未来总比预想快

设计协议或者文本格式时,应使其具有充分的自描述性以便扩展。
设计代码是,要有很好的组织,让将来的开发者增加新功能时无需拆毁或重建整个架构。

KISS

Unix哲学一言以蔽之:
KISS原则:Keep It Simple,stupid!

态度:
如果不确定什么是对的,那么就只做最少量的工作,确保完成任务就行,直到明白什么是对的。
软件设计是一门技艺。
我们应该不断追求卓越。
不要重复制造轮子。
善用工具,尽可能将一切都自动化。

Unix编程艺术.pdf