02 July 2014

前言

7月2号是刚工作的第二周周末,彼时完全没有Rails项目经验,想着怎么从公司已有的项目中学习,从网上找到的关于Rails项目阅读的回答。

四个月后,整理有道笔记时,偶然翻到,先在看来还是很有启发的。

##正文

问题

  1. 代码改动很难不出错,怎么才能减少。你说TDD/BDD..?改一点,测试一点。如果源代码根本就不写测试呢?(这情况还不少),或者他用的测试是你不熟悉的(不熟悉测试),比如源代码用的是Test:Unit,而你只会用Rspec…..?
  2. 理解,理解,还是理解!怎么才能更好的理解源代码,举例源代码一下controller里的方法很长?一个model里有很多的方法?有的很难理解或者出现在错误的地方本应放到observer,却呆在了model里?
  3. 再有就是视图了。开发或理解控制器、模型等还算容易,看视图真的一点头绪都没有。能否给点建议?

附注:因为在github上下载并认真的看了几个别人的项目,但却经常感到力不从心,不得要领,所以来此提问。希望有经验的能够帮忙解答一下~~

应个人水平不高,可能有些问题过于简单或者问得过于模糊,但请给点建议或宝贵经验(特别是高手或有经验的人)就更好了。不甚感激!

回答不必一一对应,只希望有经验或者遇到过类似问题的,恰好看到本文的,能够回复一下。 别人给你一段源代码(工作过程中),或者你从github上下载了一份,想对它进行了解并改进。如何读源代码?除了源代码,你手头上的东西不多,不要说给作者发个邮件,让他帮忙解释一下。~~

回答

先说一下个人理解:

  1. 先看gemfile,看用到了什么插件,并对插件进行简单的注释。对不懂用的插件做上标记… …如果写代码的人用rails plugin install安装呢?当然插件可以在vendor里找到,可有的插件是作者自己写的。怎么办?

  2. 对于自己熟悉的插件就不多说了,对于没用过或没听说过的赶紧的学习、理解它,通过githubrailscasts、google、项目的官网等。

  3. 通过对db/schema.rb文件还有app/models的查看知道表间关系,能够画出简单的ER图。有的人把schema.rb删了,甚至和db/migrate迁移文件删了才开源的(确实遇到过),怎么办? 可以通过rake任务dump出schema.rb

  4. 查看controllers控制器——角色(如游客、普通用户、管理员等)——action明白角色和对应权限。如:对于Products控制器上的游客 可以index,show,普通用户还可以new,create,update,edit,管理员还可以destroy… ….此外,对于非GET请求的(没有对应视图的)可以做上简单的记号… …理解功能特殊情况举例,有的人把验证authenticated_systeml.rb写到lib里,然后autoload… …怎么特殊处理?

  5. 角色——权限动词——资源,这个可以根据第4步,模仿cancan,用框图(用例的框图)的形式画出来… ….理解权限

  6. 代码结构格式化。这里指的每个人都有自己写代码的习惯,有人喜欢格式宽松的,有人喜欢严紧的。对于缩进、空格、换行等,可以把源代码的“长相”变美观一点,更符合自己的品味… ….并不是改动代码… …

本人的理解就到这了,还有下面的这些。

  1. 改动前应能够找出各个模块(Module)间的接口,在不改变接口的情况下,可以改变模块内部结构,这里就是重构的思想。

  2. 对要“删除”的代码或文件夹在不确定的情况下,并不是真正的删除,可以注释或改变文件名,最好能够加上时间戳以提醒自己。删除后提交github

  3. 对源代码的增、删、查(查找接口,方法等等)、改应该分步进行,并且提交github

  4. 分步重构。这个和3差不多,不要一下子改动太大,对已更改的能够容易还原。

知乎上回答

注: 该回答版权属于庄表伟。

推荐的《代码阅读方法和实践》,阅读别人遗留的代码,这对能力的提升而言是个好机会。

我们可以用拼图这样的游戏,来做一个比喻。一地的碎片,你如何将他们尽快的拼在一起?

  • 寻找边角的块(除了四边都是凹凸的块之外,其他有一到两条边是直线的块,会少得多,也更容易辨认与拼接。)系统的边界
  • 将碎块按大的色块分类,从一次查找,变成二次查找。系统的模块
  • 一开始碎块最多的时候,是最困难的时候,需要足够的耐心、细心,以及一点点的运气。
  • 如果你的记忆力足够的好,碰到的碎块能够在脑子里留下一定的印象,那么有助于你快速找到匹配的碎块。
  • 经验能够帮助你提高效率,熟能生巧。这是一个体力活,不是什么智力性的事情

回到代码阅读,我们来做一个类比:

  • 寻找代码中最明显的入手处,比如main函数,core文件夹,model、view、controller的三种大类等等。
  • 从理解文件夹文件名开始,而不是一上来就埋头进入源代码之中。
  • 一个好的全文搜索工具,能够帮你找到相关的代码与片段,渐渐的,看起来一团乱麻的代码,就会显现出各种可以被理解的关联出来。
  • 记忆力总是有用的,在脑子里绘出整个系统的架构,并且补充越来越多,越来越清晰的细节。
  • 一样是熟能生巧。
  • 相比拼图,代码阅读还要容易一些,你不需要理解全部的代码,有一个大致的理解以后,就可以先放过一些不太重要的细节

一些源代码相关的内容:

知其所以然

有一句俗语叫做:知其然,更要知其所以然。用在任何学习科目上,几乎都是恰当的。所以然包括哪些内容?“架构决策”、“代码风格”、“领域知识”、“编程技巧”等等内容,都算作是所以然的一部分。

  • 架构决策 通过深入阅读和分析源代码,理解整个项目,为何像这样,而不是那样做架构设计。其间蕴含着项目作者的经验和智慧,理解了这个,将是一种巨大的收获。
  • 代码风格 每一种语言、每一个社区、每一个开发者群体,甚至每一个开源项目,都有其独特的代码风格,这种风格,有其背后的合理性,也有很多是来源于某种开发哲学的思考。理解一种代码风格,就是理解一种思考的模式,一种思想的体系。能够多了解一些不同种类的代码风格,对于提高软件开发能力,将有很大的帮助。
  • 领域知识 有些代码不容易看懂,很重要的一个原因,是这个项目所涉及的领域,我们没有什么深入的了解。多年的程序员经验告诉我,要做好某一个行业的软件,一定要成为某一个行业的内行。甚至要比那个本行业的业内人士,更加精通。因此,一个优秀的程序员,通常是能够跟你聊多个不同行业的话题的。强大到你几乎无法分别他的 是不是业内人士。因此,通过理解开源项目,进而理解相关的领域知识,会有很多收获。
  • 编程技巧 阅读优秀的开源项目的代码,有时候很像是看一本好书。细细品味,慢慢的体会。我们会发现一点一滴的“妙处”。这些妙处凝聚了程序员的巧思妙想,能够体会得越多,对我们的帮助也就越大。

所以然还包括的一些内容:

  • 个人偏好 开源作者也是普通人,他们有很多观点和取舍,未必能够说服他人,只能算是他们自己的偏好。而他们将自己的偏好表达在代码里,有些时候,我们能够很容易理解(因为我们也是这样想的)。有些时候,我们就会感觉很不解,而且,常常会发生的一类故事就是:某某大牛写了一个开源项目,另一个大牛有感觉不爽的地方。提了意见建议,人家又不肯改。结果,这另外一个大牛,就一怒之下,另起炉灶,写了一个新的开源项目。
  • 历史原因 有一篇很有意思的文章,解释了《为什么Vim使用HJKL键作为方向键 》,其实原因很简单。当Bill Joy创建Vi文本编辑器时,他使用的机器机器是ADM-3A终端机,这机器就是把HJKL键作为方向键的。

如何搞清楚这些所以然呢?

  • 思考 当然,这种思考应该伴随我们”通过开源项目,学习软件开发“的始终。但是,从方法论来说,可以尝试从以下一些角度出发来思考:
    • 如果我来做一个,会如何去做?思考问题的方式。
    • 如果能够对这个项目做减法,我可以去掉那些模块和代码?真的能够去掉吗?
    • 通过阅读单元测试,理解开发者的设计思路。
    • 尝试做一些破坏或者修改,来理解项目中的那些做法。这个在下一章会更详细的讨论。
  • 讨论 到开源社区去,发起一些讨论。当然,前提是你必须经过足够深入的思考。不要尽是问一些傻问题
  • 向作者提问 与上面的讨论类似,前提是要先思考。当然,还有一个讨巧的办法,你可以提出:翻译这个开源项目的英文文档,然后,对方当然会很高兴——国际化了嘛。然后,你可以在翻译的过程中,提出各种各样的问题。。。
  • 阅读指南 有些著名的开源项目,本身也非常复杂,所以会有一些文档与书籍:《Linux内核代码分析》、《MySQL源码解读》、《PHP源码分析》等等。如果有心学习这样的大型开源项目,这种入门指南,也是很有价值的。但是,这毕竟是别人嚼过的饭,肯定不如自己去啃来的香。所以,还是回到那句老话,源代码才是最有营养的。

说的再好听,关键好要去动手实践。




傲娇的使用Disqus