[拇指飞动]读《程序员修炼之道:从小工到专家》
在很多Must Read推荐书目中,<The.Pragmatic.Programmer_From.Journeyman.to.Master[1999][CHS][PDF]>(《程序员修炼之道:从小工到专家》)俨然在列,Piaoger自然也想看看,Kindle在手,倒也容易.
>> 注重实效的程序员的特征
早期的采纳者/快速的改编者: 具有技术和技巧上的直觉,喜欢试验各种事物,能很快掌握新东西,并将其与你的知识结合起来,你的自信来自于经验;
好奇: 喜欢提问,是收集知识的小松鼠,每一条小知识都可能影响到今后几年的某项决策。
批判的思考者
有现实感: 你会设法理解你所面临的每个问题的内在本质,这样的现实主义给了你良好的感知能力。
多才多艺: 你尽力熟悉广泛的哦技术和环境,并且努力工作,以与各种新发展并肩前行,尽管你现在的工作也许只要求你成为某方面的专才,你去总是能够转向新的领域和新的挑战
>> 破窗理论
破窗户理论在很多软件工程书籍上都有提及。
-----------------------------------------------------------------------------------
一个房子如果窗户破了,没有人去修补,隔不久,其它的窗户也会莫名其妙地被人打破;一面墙,如果出现一些涂鸦没有被清洗掉,很快的,墙上就布满了乱七八 糟、不堪入目的东西;一个很干净的地方,人们不好意思丢垃圾,但是一旦地上有垃圾出现之后,人就会毫不犹疑地抛,丝毫不觉羞愧。
美国斯坦福大学心理学家菲利普·辛巴杜(Philip Zimbardo)于1969年进行了一项实验,他找来两辆一模一样的汽车,把其中的一辆停在加州帕洛阿尔托的中产阶级社区,而另一辆停在相对杂乱的纽约 布朗克斯区。停在布朗克斯的那辆,他把车牌摘掉,把顶棚打开,结果当天就被偷走了。而放在帕洛阿尔托的那一辆,一个星期也无人理睬。后来,辛巴杜用锤子那 辆车的玻璃敲了个大洞。结果呢,仅仅过了几个小时,它就不见了。以这项实验为基础,政治学家威尔逊和犯罪学家凯琳提出了一个“破窗效应”理论,认为:如果 有人打坏了一幢建筑物的窗户玻璃,而这扇窗户又得不到及时的维修,别人就可能受到某些示范性的纵容去打烂更多的窗户。久而久之,这些破窗户就给人造成一种 无序的感觉,结果在这种公众麻木不仁的氛围中,犯罪就会滋生、猖獗。
-----------------------------------------------------------------------------------
当你所在的团队和项目的代码十分漂亮,编写整洁,设计良好,并且很优雅,你可能会格外注意不去把它弄脏,因为你不想成为第一个把它弄脏的人。
>>做变化的催化剂,对付启动杂役(Start-up Fatigue)
有些情况下,你也许确切的知道需要做什么,以及怎么去做。整个系统就在你眼前——你知道它是对的。但请求许可去处理这个事情,你会遇到拖延和漠然。大家要成立委员会,预算要批准等等。每个人都会护卫自己的资源。有时候这叫Start-up fatigue(启动杂役)。
Startup Fatigue是通向成功之路必须克服的障碍。 这时候你需要像做"石头汤"一样,先给出一个东西,让他们看到未来,你就能让他们聚集到你身边。
>> 记住Big Picture
时刻留意Big Picture,免得成为温水中的青蛙。持续不断观察周围所发生的事情,而不仅仅限于正在做的事情。
[Piaoger]:Kodak曾经NiuB一时,如今却陷入困境,当年的技术精英却落得个夜班司机的下场。
>> 敢于认错
在所有的弱点中,最大的弱点就是害怕暴露弱点。
>> 定期为你的知识投资
每年至少学习一种新语言
每季度阅读一本技术书籍
也要阅读非技术书籍
上课
参加本地用户组织
试验不同的环境
跟上潮流
上网
>>DRY: Don't Repeat Yourself
系统中的每一项知识都必须是具有单一、无歧义和权威的表示。下面归纳了不同的重复:
强加的重复(Imposed Duplication):开发者觉得他们无可选择,环境似乎要求重复
信息的多种表示:我们常常需要以不同的形式表示同一种信息;编写C/S程序时,在客户端和服务器端使用了不同的语言,并且需要在两端都表示某些共有的结构。
解决办法: 编写简单的过滤器或者代码生成器。在每次Build代码时,使用简单的代码生成器,根据公共的元数据表示构建多种语言下的结构。
[Piaoger]:感觉COM技术用到的IDL就有些意思。
代码中的文档:把低级的知识放在代码里,而将注释保留给其他的高级说明,否则我们就在重复知识,因为每一次改变都意味着既要改变代码,还需要更新注释,注释将不可避免变得过时,而不可信任的代码比没有任何注释更糟糕。
无意的重复(Inadvertent Duplication): 开发者并未意识到他们在重复信息
设计上的一些错误
无耐性的重复(Impatient Duplication): 开发者偷懒导致的重复,因为更省事而重复
拷贝代码
开发者之间的重复(Interdeveloper Duplication): 同一团队或不同团队之间的重复
Reuse/Communication
>> 正交性:消除无关事物之间的影响
有助于提高生产效率和降低风险。
常用技巧:
代码解耦
避免使用全局数据
避免编写相似代码
好处:
提高效率: 改动局部化/促进Reuse/便于组合
降低风险: 可以将有问题模块隔离开来/系统更健壮/更便于测试/不会与特定的供应商绑在一起
>>可撤销性: 不存在最终的决策
保持代码的灵活性,还需维持架构、部署甚至供应商集成等多种领域的灵活性。
>> Tracer Bullets(曳光弹)
你需要在黑夜中,用曳光弹来找到目标。
传统的工程方法: 把代码划分成模块,然后对模块进行编程,然后把模块组合成子装配,再对子装配进行组合,直到有一天你拥有了完整的应用为止。直到此时,才能把应用作为一个整体呈现给用户,并进行测试。
"曳光弹"类的方法则尤其适合于面临着大量的未知事物的项目,需求含糊不清,算法、技术、语言或库不熟悉,充满着变化。
曳光弹代码的好处:
用户能够及早看到能工作的代码
开发者构建了一个他们能够在其中工作的结构
拥有了一个集成平台
拥有了可以演示的东西
你将能够感觉到工作进展
>> 曳光代码 != Prototype
>> Estimation
估算是为了预测风险,以避免发生意外。
估算的精度因势而异。
>> 橡皮鸭
找到解决问题的办法,有一种非常简单却又非常有用的办法就是想别人解释它。
也许你只需放在一个能在澡盆里上下晃动的橡皮鸭,对你不断你点头。它无需说任何话,你只是一步步解释代码要干什么,常常就能让问题从屏幕上跳出来,宣布自己的存在。
>> 代码生成器:编写能编写代码的代码
无论何时,你发现自己在设法让两种不同环境一起工作时,你够应该考虑使用主动代码生成器。
代码生成器的输出并非只有代码,HTML/XML/PlainText都可能是"目标代码".
代码生成器分为两种:被动代码生成器和主动代码生成器。
被动代码生成器只运行一次来生成结果,然后结果就变成独立的,它与代码生成器也剥离开来。
主动代码生成器则在每次需要其结果的时候都被使用。结果是用过就用过的,它总能由代码生成器重新生成。主动代码生成器为了生成结果,通常要读取某种形式的脚本或者控制文件。
利用被动代码生成器,你可以生成查找表,创建新源文件或者编程语言转换。下面是主动生成器的两个例子:
一个数据库应用例子里,你必须处理两种环境-数据库和你用来访问它的编程语言。你有一个Scheme,需要定义Low Level的结构,来反映特定的数据库表的布局,尽管你可以直接对其进行编程,但违反了DRY原则:Schema的知识就会在两个地方表示,当Schema变化是,你需要记住改变相应的代码,如果某一列从表中被移除,而代码没有随之改变,连编译错误也不会有,只有等你测试开始失败或者用户打电话过来是,你才会意识到你错在什么地方了。
更好的办法就是读取Schema,使用它来生成Struct的源码,这样的话,无论何时Schema发生变化,用于访问它的代码也会自动变化,如果某一列北移走,那么它在Struct中相应的字段也将消失,任何使用该列的更高级代码将无法通过编译。你在编译的时候就能够抓住错误,而无需等到实际运行。
--------------------------------------------------------------------
--------------------------------------------------------------------
另一个例子就是反正在不同编程语言被用于同一个应用时,为了进行通讯,每个代码库将需要某些公共信息(数据结构、消息格式和字段名),要使用代码生成器而不是重复这些信息,一种办法是从一种语言的源文件中解析出信息并将其用于生成第二种语言的代码。更好的办法是用一种更为简单、语言中立的表示形式来表示它,并为两种语言生成代码,常常更为简单,COM用到的IDL文件就是一个很好的例子。
>> 你不可能写出完美的软件
没有人可以编写完美的代码,要针对自己的错误写出防卫性的编码。
Design By Contract(Precondition,Postcondition,Class invariation)
死程序不说谎(Crash early)
断言式编程
异常/Error Handler
>> 工欲善其事,必先利其器
IDE/Shell
>> Algorithm Speed
--------------------------------------------------------------------
--------------------------------------------------------------------
>> 无处不在的自动化, 一切都要自动化
构建自动化/自动化管理/ 网站生成自动化
>> 实现小型语言
实现小型的DSL,这一点在云风的Blog中也可以看到,尽管我们也可以使用Python或者Lua之类的脚本语言,但毕竟不是Domain-spcific,用起来难免会有些不顺手。
>> 把抽象放进代码,把细节放进元数据
元数据驱动的好处:
降低设计耦合;
迫使推迟细节处理,创建更健壮、更抽象的设计
无需重新编译应用就可以进行定制,还可以利用这种特性绕开正在运行产品的Bug
与通用数据结构相比,可以通过领域语言来表达
>> 建立藏书库
这几年,书买了不少,还收藏了N多电子书,还有两台Kindle,拇指飞动,感觉不错。