《程序员应该知道的97件事》

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gongjun12345/article/details/80155124

1. Act with Prudence

无论一个计划刚开始看着多合理,你依然无法避免在某些时候承受压力。

当你发现你出于选择“做得好”或是“做得快”时,总会认为先选择“做得快”,之后再修复他。

当时对自己,对团队,对客户承诺时,你是认真的。

但是,通常而言,你会把注意力放在遇到新的问题上。

这类推迟的工作被称为技术债务。

这类是故意的技术债务,不应和无意的技术债务混淆。

像贷款一样,短期从中获利,但事后需要花更多精力才能解决它。

代码中的捷径让代码很难增加新的功能或重构。

他们是缺陷的温床。越不管,越糟糕。

当你开始着手处理一开始的问题时,这个问题上面已经覆盖一大堆设计很不合理的代码。

实际上,总是当问题严重要你必须要解决时,你才会回头来修复他。

到那时,这个问题总是会非常难处理,而且你无法承受这样的时间和风险。

当你必须引发技术债务以满足截止时间或实现一个小功能时。

尽量不要出于这样的境地,但如果身不由己,那就去做吧。

但,你必须跟踪技术债务并及时偿还,否则情况就会急转直下。

一旦你决定让步,写一个任务卡或在问题单系统上记录下来,保证这件事不会被忘记。

如果下次迭代前就偿还技术债务,代价是最小的。遗留技术债务会产生技术利息。

这种技术利息需要被追踪,让代价可评估。

这样可以强调项目的技术债务对商业价值的重要性,并让弥补工作得到合适的优先级。

决定如何计算和追踪技术债务利息取决于特定的项目,但你必须追踪它。

尽快偿还技术债务,否则这将是轻率的。

2. 采用函数式编程原则

     函数化编程,在主流编程社区获得了新的注意。

因为当软件产业逐渐转向多核时,功能范式的应急特性能很好得解决这样的挑战。

掌握函数式编程能极大地提升代码质量。深入理解和应用函数编程,你的代码会展现出更高等级的引用透明。

引用透明性是非常令人满意的特性:函数根据相同的数据,恒定给出相同的输出,无论该函数何时何处被调用。

就是说,函数尽量少依赖环境,最好没有依赖。这样就没有可变状态的副作用。

命令式代码的缺陷主要归因于交互式变量。

可见的语意可以缓解特定情况的量值。

根本原因是毫无节制的可变性。

小型化的函数,不需要带有太多参数,便于debug,易于定位异常参数

4.将代码规范自动化

遵守代码规范如果不是自动化的,将会是十分枯燥的。

代码规范可以让大家在项目里工作自如。项目的开始到结束都保持开发速度。

  • 在编译过程中,加入代码格式转换,每个人在编译代码时就能自动执行
  • 用静态代码检查工具,扫描代码,若发现不需要的模板,打断编译
  • 不要只计算代码覆盖率,需要自动检查测试结果,如果覆盖率太低,就打断编译。

代码规范是可以动态改变的,不一定一成不变。随着项目进行,有的代码规范不一定变得必须的。

5. 代码简化之美

Beauty of style and harmony and grace and good rhythm depends on simplicity

可靠性

可维护性

开发速度

难以描述的质量之美

对美的感知相当依赖于个体的背景,类似于我们对任何事物的理解都取决于我们的背景

上网找开源代码学习,找知名专家,学者写的代码。

我发现这些代码对我有共鸣,我认为的漂亮的代码,都有一些共有的特性。

其中最主要的,就是简单。无论这个应用或系统多复杂,单独的模块总是很简单。

简单的对象,包含了简单的函数和简单的命名。

每个单独的部分保持简洁,有单独的职责,和其他部分保持弱耦合的关系。

有些人认为每个函数5-10行是极限,但我认为如此的简洁,无论如何都是我们一直的追求。

美丽源于简单。

6.  在重构之前

在重构前,考虑如下问题

1、在开始重构前,先评估现有的代码库和测试用例库。可以有助于理解现有代码的优点和缺点。

以便你能保持原有有点的同时,还能避免错误。

我们都相信自己能比以前的系统做得更好,直到我们没有从前人上吸取错误的教训,导致我们做的没有前者好,或更差。

2、避免重构全部的事。最好能尽可能重复利用原有代码。扔掉旧的代码,意味着放弃了数月数年的测试,一线代码,以及特定的workaround你没有发现的。

如果你不把这些记录在内,新的代码会出现同样的严重错误。这会浪费大量的人力物力,以及花费数年积累的知识。

3、大量渐进式优化比一次改头换面的要好。渐进式优化允许你通过反馈来评估对系统的影响。

同一时间,少量的测试问题便于处理,也便于管理。

4、在每次开发迭代后,保证现有测试通过很重要。并且增加新的测试用例,已覆盖新加的改动。不要把原有的测试用例在不加思考的情况下删除。虽然表面上,这些测试对新的设计可能并不适用,但深挖一下,总是能找到特定的原因,为何需要增加这样的测试。

5、个人的喜好不应该被加入进来。如果你只是不喜欢这个代码的样式或架构,这不能成为重构代码的原因。

6、新技术的引入不是重构的充分必要条件。除非成本效益分析显示,新的语言或架构能给功能面,可维护性或效率上带来显著的提升

7、人总会犯错,重构无法总是保证能比旧有代码要好。是人就无法避免犯错。

7. 小心共享

重用代码的上下文检查十分重要。

虽然减少了几行代码,但却增加了相互依赖。对上下文的依赖是十分危险的。

创建共享的代码库之前,仔细检查代码的上下文

8. 童子军原则

童子军规定:永远保持营地比你来之前更干净。

永远保持一个模块比你签出前更干净。

软件系统就能不断进化和改善。

将代码弄得一团糟的行为,应该像社会上乱丢垃圾一样不可接受。

每个人不只是维护自己的模块,同时也能将其他模块的代码做清理,

这样软件系统无可挽回的退化就会停止,也会逐渐变得更好。

9. 指责别人代码前,先检查自己的

开发者总是认为自己的代码不会出错,不过最后都证明是开发者自己的错误。

如果谁报告了一个问题,你无法复制,去看看他们怎么做的。

他们可能做了你从没想到过的,或不同的顺序来做。

排除所有的不可能,剩下的事,再怎么不可能,也是真理。

10. 小心选择你的工具

现代应用程序很少空手起步。他们是利用现有工具组装而成。

应用程序在大小和复杂程度上不断扩张。而开发的时间缺在缩短。

如果能更集中精力在业务层代码,而不是底层代码,开发者的时间和智慧的利用率就能提高。

广泛使用bug更少的元件或框架

网上有很多高质量代码,可以降低开发费用并找到更多专家级的开发者。

许可证问题,使用GNU的代码,必须同时公布其源代码,这在一些公司是不被允许的。

一开始只对十分有必要的工具做升级。(从小范围开始,只使用一些绝对必要的工具)

用一些中间件来替代,避免一些根基部分的代码修改。

12. 代码就是设计

因建造成本的低廉,导致对项目的不负责任。随时可以推倒重来。
 

13. 代码布局

随意的代码缩进的修改,会导致对代码的误导。

我们每天都在阅读和修改代码,所以对此需要做优化,有如下三点:

便于扫描

有表现力的布局

     团队首先要同意自动化格式工具做基本的修改

     团队对代码格式要意见一致,这样才会随手保持代码风格。

紧凑模式

     保持代码的紧凑,函数尽量在一个屏幕下。

好的代码像一首诗

14. 代码审核

code reviews should ask lead developer or architect to do

代码审核应该让主力开发人员和架构师参与,并且做为严格和正式的流程。

代码审核员需要时间来阅读代码和了解每一项系统细节。

代码审核的目的是分享知识,建立代码规范共识。

确保注释是建设性的。

让不同的角色参与代码审核,避免团队中资深的人影响到代码审核。

例如,有的人关注文档,有的关注异常检查,有的关注功能性。

这种方法能分担代码审核的负担。

每周花一天做代码审核,每次都轮换不同的代码审核人。每个人都转换不同的角色。

让初学者参与,即使他们没有经验,但新鲜的大学知识可以带来不同的视角。

让有经验和知识的专家参与。他们能更准确发现有隐患的代码。

格式转换工具能让会议更顺利,避免会议上谈论代码格式的问题。

让代码审核变得有趣十分重要。如果审核会议是痛苦和枯燥的,这就很难激励每个人。

代码审核的目的是分享知识。把刻薄的评论变成轻松的讨论。

15. 理性编码

把代码分割成小于10行的小块。
每个小块都应该便于对其状态的解读,包括函数名,函数变量的值。这样片段的功能可以描述为一个小任务。
这样的方式可以将解读更简单。这样的片段可以抽象成前提条件和后置条件。

  • 不要用goto,会导致代码高度耦合。
  • 不要用可变的全局变量,这会导致代码相互依赖。
  • 每个变量最好拥有最小的作用域
  • 让对象不可变
  • 提高代码可读性,两个片段之间用空白行隔开
  • 让代码可自编文档化,用可描述的变量名,对象名,类型名,函数名
  • 如果要用嵌套的片段,改为函数
  • 函数尽量短而精,以前有24行的限制,现在也适用
  • 函数参数尽量少,最多4个。将相关参数组合成对象或结构体,这样的一致性有助于解读。
  • 每个单元代码,从块到库,都应该有一个确定的接口。联系越少越方便解读。

16. 注释的建议

确保你的注释是帮助理解代码,而不是将其弄得更复杂。

你的开头注释应该能提供足够的信息,帮助其他程序员使用你的代码,而不需要读一遍。

内联的注释则帮助下一个开发者能修复问题或扩展其功能。

17. 只注释晦涩难懂的代码

18. 持续学习

多读书,杂志,博客,推送和网页。如果对某个题目想了解更深入,考虑加入一个mail list或新闻组

如果你的确想沉浸到某个技术,动手写点代码吧

尽量和导师一起工作,成为最优秀的人会阻碍你的学习。可以向更聪明和更有经验的人学习。如果找不到,就move on。

使用虚拟导师,在网络上找到你喜欢的作家和开发者,多看看他写的东西,订阅他的博客。

掌握你使用的框架和库,掌握其如何工作会让你使用它更顺手。

如果你修复一个bug或分析一个问题,理解他是如何工作的。很可能网上可能会有同样的人处理过。

有一种学习的途径是把他将给别人听,当别人听你讲并问你问题,这会激励你更主动学习。

加入或开始一个针对一门语言,一门技术,一项协议的学习团队

参加会议,有很多网上免费的会议视频

通勤路程太久?听听播客。

在代码库上跑一个静态分析工具,或分析代码的warning,找到原因并修复。

听从《程序员修炼之道》一书的建议,每年学一门新的语言,或至少学一个新技术或工具。

不一定每个学习的都和技术有关,学习领域相关的可以让你更理解需求和解决商务问题。让自己更高效的工作也是一个不错的选择。

回校学习。

19. 易用不是一种能力

设计一个好用的api的重要性和挑战性已经被提及很多次了。

有经验的程序员知道好的API遵循一致的抽象层次,代码的一致性和对称性,由表现力的语言组成。

为了避免高屋建瓴,我们选一个特定的API设计策略,我经常遇到的,参数的便利,都出于如下两个原因:

我不希望别的类需要做两个单独的函数来做这一件事。

为何需要做一个几乎一样的方法,我只需要在这个函数中增加一个switch。

除非设计得很好,这样的参数会导致API可读性的下降。函数调用写为:

parser.processNodes(text, false),其实对于没有看过文档的人完全无法理解。这样的函数只是方便了开发者,而不是调用者。

21. 区分业务异常和技术异常

猜你喜欢

转载自blog.csdn.net/gongjun12345/article/details/80155124
今日推荐