【软件工程】《程序员修炼之道》书摘
编程是一种技艺。编程是一项艰难的工作。你不应该局限于特定的技术,而是应该拥有足够广博的经验基础,以让你能在特定情况下选择好的解决方案。
注重实效的程序员的特征:
- 早期的采纳者/快速的改编者
- 好奇
- 批判的思考着
- 有现实感
- 多才多艺
注重实效的哲学:
注重实效的程序员处理问题、寻求解决方案时的态度、风格、哲学
- 关心你的技艺。
- 思考!你的工作。
THINK!,是注重实效的程序员的mantra(颂歌)
- 提供各种选择,不要找蹩脚的借口。
- 不要容忍破窗户——低劣的设计、错误的决策、或是糟糕的代码。
- 做变化的催化剂——参与正在发生的成功更容易,让人们瞥见未来,你就能让他们聚集在你周围。
- 记住大图景,持续不断地观察周围发生的事情。
- 使质量成为需求问题。
- 定期为你的知识资产投资。
- 每年至少学习一种新语言
- 每季度阅读一本技术书籍
- 也要阅读非技术书籍
- 上课
- 参与本地用户组织
- 试验不同环境
- 跟上潮流
- 上网
- 批判的分析你读到的和听到的。
- 你说什么和你怎么说同样重要。交流越有效,你就越有影响力。
注重实效的途径
这些途径作为零散的段落写在关于设计、项目管理或编码的讨论中
- 不要重复你自己——DRY原则:系统中的每一项知识都必须具有单一、无歧义、权威的表示。
- 让复用变得容易——营造一种环境,在其中找到并复用已有的东西,比自己编写更容易。
- 消除无关事物之间的影响——提高生产率和降低风险。
- 设计:如果我显著的改变某个特定功能背后的需求,有多少模块会受影响?
- 工具箱与库:它是否会迫使你对代码进行不必要的改动?
- 编码
- 保持解耦
- 避免使用全局数据
- 避免相似的函数
- 测试:每个模块都拥有自己的、内建在代码中的单元测试,并让这些测试作为常规构建过程的一部分自动运行。
- 文档:显著的改变外观,而不用改变内容。
- 不存在最终决策——为可能出现的意外事件做准备。
- 用曳光弹找到目标——我们要找到某种东西,让我们能够快速、直观和可重复的从需求出发,满足最终系统的某个方面要求。
- 曳光代码:简约却完整,并构成了最终系统的骨架的一部分。
- 原型制作:生成用过就扔的代码。
- 为了学习而制作原型——其价值不在于所产生的代码,而在于所学到的经验教训。
- 靠近问题领域编程——通过在更高的抽象层面上编码,你获得了专心解决领域问题的自由,并且可以忽略琐碎的实现细节。
- 估算,以避免意外发生。
- 通过代码对进度进行迭代。
基本工具
工具放大你的才干
- 用纯文本保存知识——通过纯文本,你可以获得自描述的、不依赖于创建它的应用的数据流。
- 利用
shell
命令的力量。 - 用好一种编辑器。
- 总是使用源码控制,确保每样东西都在源码控制之下。
- 调试就是要解决问题:
- 要修正问题,而不是发出指责。
- 调试第一法则:不要恐慌。
- 不要假定,要证明。
- 学习一种文本操纵语言——快速构建实用程序,为你的想法建立原型。
- 编写能写代码的代码。
注重实效的偏执
你不可能写出完美的软件
- 通过合约进行设计——“懒惰”的代码:对开始之前接收的东西要严格,而允诺返回的东西要尽可能少。
- 早崩溃——要崩溃,不要trash。
- 如果它不可能发生,用断言确保它不会发生。
- 将异常用于异常的情况——把异常用作正常处理会破坏封装。
- 分配资源要有始有终。
- 以与资源分配的次序相反的次序解除资源的分配;
- 在代码的不同地方分配同一组资源时,总是以相同的次序分配它们。
Bend or Break
为了赶上变化的步伐,我们要尽可能编写宽松、灵活的代码
- 使模块之间的耦合减至最少。
- 要配置,不要集成——要用元数据描述应用的配置选项。
- 抽象放进代码,细节放进元数据。
- 迫使你解除设计的耦合;
- 迫使你推迟细节处理;
- 无需重新编译应用;
- 可以通过接近问题领域的方式表示元数据;
- 用相同的应用引擎、但不同的元数据实现不同的项目。
- 分析工作流,以改善并发性。
- 用服务进行设计:我们创建的其实不是组件,而是服务——位于定义良好的、一致的接口之后的独立、并发的对象。
- 总是为并发进行设计。
- 使视图与模型分离——用低廉的代价为自己换来了许多灵活性。
- 用黑板协调工作流——协调完全不同的事实和因素,同时又使各参与方保持独立、甚至隔离。
当你编码时
编码不是机械的工作
- 不要靠巧合编程,巧合可以在所有层面上让人误入歧途。
- 深思熟虑地编程:
- 总是意识到你在做什么;
- 不要盲目地编程;
- 按照计划行事;
- 依靠可靠地事物;
- 为你的假定建立文档;
- 不要只是测试你的代码;
- 为你的工作划分优先级;
- 不要做历史的奴隶。
- 估算你的算法地阶;测试你的估算——既考虑理论问题,又考虑实际问题。
- 早重构,常重构:
- 不要试图在重构时增加功能;
- 重构前,确保你拥有良好地测试;
- 采取短小、深思熟虑地步骤。
- 为测试设计——针对合约进行设计(单元测试),可以更多避免“下游地灾难”。
- 测试你的项目,否则你的用户就得测试。测试是技术,但更是文化。
- 不要使用你不理解地向导代码。
在项目开始之前
在项目开始之前先建立某些基本准则
- 不要搜集需求——挖掘它们,需求很少存在于表面。
- 成为用户:与用户一同工作,以像用户一样思考。
- 抽象比细节活的更长久。
- 使用项目词汇表——定义项目中使用专业术语和词汇地地方——以确保一致性。
- 不要在盒子外面思考——找到真正地盒子——确定真正地约束。
- 倾听反复出现地疑惑,等你准备好再开始。
- 对有些事情“做”胜于“描述”。
- 不要做形式方法地奴隶——不要盲目的采用任何技术而不把它放进开发实践和能力地语境中。
- 昂贵地工具不一定能制作出更好的设计,在考察工具产出时,不要考虑它值多少钱。
注重实效地项目
从个体地哲学和编码的问题转向项目级的问题
- 围绕功能、而不是工作职务进行组织。
- 不要使用手工流程,让计算机去做重复、庸常的事。
- 无情的测试
- 早测试,常测试,自动测试;
- 要通过全部测试,编码才算完成;
- 通过“蓄意的破坏”测试你的测试;
- 测试状态覆盖,而不是代码覆盖;
- 一个bug只抓一次。
- 把英语当作又一种编程语言。
- 把文档建在里面,而不是拴在外面。
- 温和的超出用户的期望。
- 在你的作品上签名,我们是在做引以为豪的工作。