古玩赏析:中国李可染书画艺术院理事杨旭尧——“李家山水”经典传承
大家好,unix设计哲学「如何提炼办学思想」很多人还不知道,现在让我们一起来看看吧!
阅读意义《Unix编程艺术》是一本讲Unix编程的书,成书近20年,可以说是老古董了。类似于古朴的先秦时期容易出现老庄、孔孟那些深邃的思想一样,在计算机领域的早期,可能更容易看清编程的本质,更容易涌现一些深刻的思想。书中提及驱动Unix走向巨大成功背后的文化、价值观和编程原则等,其中不乏一些对软件开发之道有深刻理解的地方,我们现在耳熟能详的一些编程原则也极可能源自此书,而正如书中所说,书中的内容对于其他领域编程也有相当的借鉴意义。
文化和价值观Unix开发人员长期以来形成了很多编程原则,这些原则需要一个共同的价值观作为基础,而这就是Unix编程的文化和价值观。
问渠那得清如许,为有源头活水来。Unix的生命力之强,和它的开放、自由、灵活和趣味性是分不开的,这是Unix文化。
而关于Unix价值观,在书中,有如下几种表述:
Unix哲学注重实效,鼓励分清轻重缓急,提倡怀疑精神。
Unix哲学是这样的:
① 一个程序只做一件事,并把它做好
② 程序之间要能相互协作
③ 程序要能处理文本流,因为这是最通用的接口
Unix哲学:
① 未确定瓶颈之前,别着急修改代码
② 花哨算法通常很慢,更容易出Bug、更难实现,尽量用简单的算法配合简单的数据结构,大不了使用穷举算法
③ 编程的核心是数据结构,正确的数据结构让正确的算法不言自明
最后,书中将所有的Unix哲学浓缩为一条铁律,就是“K.I.S.S(Keep It Simple, Stupid!)”。
在笔者看来,Unix哲学或文化,其实就是提倡要像一个真正聪明的人在做事。一个真正聪明的人做事,通常都要求数据说话,不迷信权威,要看得到真正的价值,要合算,要避免因小失大,要分轻重缓急,要看长远,要简单清晰,要专注,要抓住根本,必要时使用笨方法。而Unix编程提倡的同样也是这些,提倡智慧地做事,而不是弄巧成拙。
大智若愚,大巧若拙,真正有效的方法就是去除次要因素,抓住根本,就是这么简单。所以,所谓“K.I.S.S”就是还其本原的过程。
原则相对于价值观,原则是一些较为具体的权衡准则,书中共列举了17条。
1、模块原则:使用简洁的接口拼合简单的部件
计算机编程的核心宗旨就是要控制复杂度。
控制复杂度,并没有万能药,唯一的方法就是降低系统的整体复杂度,即通过清晰的接口把简单的模块组合起来,从而让问题限于局部,不必牵一发而动全身。
这里一个很重要的手法就是问题的局部化,类似于“某个地方只因一种原因而变化,因一种原因变化的只在一个地方”。
2、清晰原则:清晰胜于机巧
代码是写给将来阅读和维护它的人的,此事与维护成本直接相关。
优雅而清晰的代码不仅容易理解,而且健壮,不容易隐含问题。
清晰的代码需要必要的注释、良好的扩展性。
复杂的代码容易滋生Bug,要避免为了一丁点儿性能提升而大幅度提升代码的复杂性和晦涩性。
笔者分析,这就是真正聪明地做事的方法,不要投机取巧,避免因小失大,弄巧成拙。
3、组合原则:设计时考虑拼接组合
如果程序间不能有效通信,那么软件就会陷入复杂性的泥沼。
Unix提倡程序为过滤器形式,其输入输出的要简单、文本化、面向流、格式与设备无关。这样,程序就彼此独立,而易于组装。
笔者认为,这是一种看透本质的设计风格,程序的本质就是“输入-处理-输出”,一切程序兼过滤器,一切消息兼文本,程序间就极易组装和协作,形式上很简单,却能实现很高级复杂的东西。
4、分离原则:策略同机制分离,接口同引擎分离
通过分离,将变化速率不同的部分分开,以实现灵活扩展。
笔者:这里有我们常见的“接口与实现分离”,多了“策略与机制分离”一说,本质上是一样的。接口和机制相对来说变化的可能性低一些,而实现和策略则可能性高一些,将两者分离开,可以使程序便于维护,并提升扩展性和灵活性。
5、简洁原则:设计要简洁,复杂度能低则低
程序员虚荣的卖弄和无节制的特性比拼,是引起程序复杂并走向失败的两大原因。
要避免落入复杂度攀升的陷阱,就必须提倡简洁为美,看重简单的解决方案。
笔者认为,我们很容易被临时性、诱惑性的东西蒙蔽双眼,又懒于思考和反省,而迷失本心,偏离了事物的本质和问题的核心,这就是复杂性的根源。
6、吝啬原则:除非确无它法,不要编写庞大的程序
体积大、复杂度高的程序维护起来就困难。
笔者:不是有这么一句话吗,最好的代码是没有代码,复杂度和问题是伴随代码而生的,代码能解决问题即可,避免添油加醋,涂脂抹粉。
7、透明性原则:设计要可见,以便审查和调试
软件系统要在设计时就把调试考虑进去,要设计为有透明性,可以一眼看出在做什么和怎么做,同时还要设计为有显见性,便于查看和监视内部状态,这样可以大幅减少调试时间,整体上较为划算。
为了达到透明和显见,程序的接口要简洁,输入输出格式要简单,从而便于调试和监视。
笔者认为:做事要长远考虑,写代码的时候也是这样,要考虑代码将来的生命周期中各个场景,如调试、测试、维护、监控等等,将这些需求纳入代码中,让相关人满意的代码就是好代码。
8、健壮性原则:健壮源于透明和简洁
健壮性表示软件在正常情况、意外条件下均能运行良好。
复杂性是健壮性的敌人,要让程序的内部逻辑透明化、简洁化。
Bug通常隐藏在处理特例的代码中,避免特例处理是保证健壮性的方法之一。
笔者:要转换维度,抓住本质,避免陷入处理各种特例的陷阱中,疲于修补
9、表示原则:把知识叠入数据以求逻辑质朴而健壮
对于人类来说,数据要比编程逻辑更容易驾驭。
在设计中,应该有意识地将代码的复杂性转移到数据中去。
笔者评注:知识是一种带来复杂性的东西,将知识由算法逻辑转移到数据结构中,是驯服复杂性的一种巧妙手段
10、通俗原则:接口设计避免标新立异
最易用的程序就是用户需要学习新东西最少的程序,满足“最小惊讶”原则。
惯例可以用来缓和学习曲线。
笔者:符合惯例习俗,不需要额外学习和注意的东西就是简单的东西,
11、缄默原则:如果一个程序没什么好说的,就沉默
“沉默是金”是Unix最为古老而持久的设计原则之一。
设计良好的程序要避免过多消耗用户的注意力,一切从简。
笔者:多即是少,少即是多。信息泛滥会导致关键信息被淹没,复杂性上升。
12、补救原则:出现异常时,马上退出并给出足够错误信息
软件要尽可能从容应付各种错误输入和自身的运行错误。如果做不到这一点,就让程序尽可能以一种容易诊断错误的方式终止。
程序要尽量“宽容地收,谨慎地发”,尽可能地兼容输入数据,而严格输出。
笔者:“宽容地收,谨慎地发”,总结得多好。
13、经济原则:宁花机器一分,不花程序员一秒
程序员的时间比机器更为宝贵时,就要考虑把事情多交给机器。
笔者:程序员真的要有经济头脑,这是真正聪明地做事的一项要求
14、生成原则:避免手工hack,尽量编写程序去生成程序
人类不善于辛苦的细节工作,由程序生成的代码总是比手写的代码廉价且值得信赖,这就是为什么会有编译器、解释器的原因。
笔者:机器擅长的事情,就交给机器
15、优化原则:雕琢前先要有原型,跑之前先学会走
“90%的功能现在能实现,比100%的功能永远实现不了强。”
“过早的优化是万恶之源”。
“先能走,再学跑”
“先求运行,再求正确,最后求快”
“最强大的优化工具恐怕就是delete键了”
避免牺牲透明性和简洁性而片面追求性能。
以上都体现了一种在功能和性能之间孰轻孰重的权衡,无疑简洁的功能是第一位的,然后才是追求性能,而原型作为两者结合体的雏形,为迈向最终目标提供了基础。
笔者:“先求运行,再求正确,最后求快”,知道轻重缓急,知道前后置关系
16、多样原则:绝不相信所谓“不二法门”的断言
没有最好,只有更好,开放、可扩展、定制化是Unix的传统,避免囿于少数设计者的想象力,造成僵化和封闭。
笔者:不迷信权威,没有最好,只有更好
17、扩展原则:设计着眼未来,未来总比预想来得快
没有终极答案,要为数据结构和算法留下扩展的空间,避免为先前的不明智买单。
设计协议或是文件格式时,应使其具有充分的自描述性以便可以扩展。
设计代码时,要有很好的组织,让将来的开发者增加新功能时无需拆毁或重建整个架构。
笔者:要为变化预留扩展,而不是超前设计(提前实现可能的变化),这是两回事
态度书中认为,除了这些文化、价值观和原则之外,人的态度也尤为重要。
1、积极主动,看到该做的就去做
看到有价值的事情就去做,短期来看似乎是多做了,但从长期来看,这才是最佳捷径。
2、乐于探索,不断追求卓越
软件设计是一门技艺,值得你付出所有的智慧、创造力和激情。否则,就会被复杂臃肿的系统和代码拖累。
3、需要用心,善用他人之力
珍惜自己的时间和精力,善于利用他人成果,避免傲娇和蛮干,尽可能自动化你的工作,把精力用在真正有用的地方。
4、游戏其中,保持快乐和激情
紧凑性和正交性软件设计和实现应该是一门充满快乐的艺术,是一种高水平的游戏。
不忘初心,工作不只是为了赚取和打发时间。
最后一个单独要提出来的就是书中关于紧凑性和正交性设计方法的论述,感觉这是一个关于软件设计很好的提法。
软件设计有两种方式:一种是设计得极为简洁,没有看得到的缺陷;另一种是设计得极为复杂,有缺陷也看不出来。而第一种方式的难度要大得多。
模块化是编写复杂软件走向成功之路的唯一方法,模块化程序注重正交性和紧凑性。
模块化的代码封装良好,不对外暴露自身实现细节,模块间仅通过API访问。
紧凑性就是一个设计是否能装进人脑中的特性。
正交性是有助于使复杂设计也能紧凑的最重要特性之一。在纯粹的正交设计中,任何操作均无副作用:每一个动作只改变一件事,不会影响其它。
正交性设计缩短了测试和开发的时间,因为那种既不产生副作用,也不依赖其它代码副作用的代码校验起来容易的多,替换也比较容易。
正交性的一条重要原则就是“不要重复自己(DRY)”,要求任何一个知识点在系统内都应当有一个唯一、明确、权威的表述,这也叫真理的单点性(Single Point of Truth,SPOT)。
SPOT原则也适用于数据结构,要求“无垃圾,无混淆”,“无垃圾”指数据结构要最小化,不能太通用,及表示不可能存在的情况。“无混淆”是指在真实世界中绝对明晰的状态,在模型中也应该同样明晰。SPOT倡导数据结构的模型状态和真实世界系统的状态能够一一对应。
要提高设计的紧凑性,有一个精妙但强大的方法,就是围绕“解决一个定义明确的问题”的强核心算法组织设计,避免臆断和捏造,即形式化。凭经验法则得出解决方案的方法称为试探法(启发法),不同于形式法,它不一定总是正确,需要处理大量特例和边界情况,必须采用某种恢复机制作为后备,会引发复杂性,应尽量避免。
为了使设计变得更紧凑、更正交,需要考虑将特例、偶然情况从问题中分离出去,避免依附于不被注意的假设。
结束语全书内容很多,还有很多内容用来具体阐述这些原则和方法,如果感兴趣,可以购买或搜索电子书进一步阅读。