ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:31.51KB ,
资源ID:24029326      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/24029326.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(5 理解源代码精品文档28页.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

5 理解源代码精品文档28页.docx

1、5 理解源代码精品文档28页# 5. 理解源代码在这一章中,只打算讨论以命令式编程范型为主的语言,因为其他的编程范型的开源项目,笔者接触太少了(期待各类达人多多补充)。# 5.1. 静态理解阅读一个开源项目的源代码,通常都很容易。大多数开源项目的托管网站,都提供了无需下载,直接阅读源代码的功能,比较有趣的是,大家可以比较一下 sourceforge、google code以及github的查看源代码的功能。这分别代表了老、中、青三代开源托管平台,对于查看代码的重视程度。# 5.1.1. 目录结构好的开源项目,通常会选择合理的目录结构,来组织自己的代码。而所谓合理,通常意味着遵循最常见的约定俗成

2、。比如:|目录名|含义|conf/configure|各种配置文件|src/source|项目的源代码|doc/document|项目文档|test/unittest|单元测试|tools/utils|相关工具|lib|库文件|app|应用相关的文件(在web项目中经常出现)|controllers|控制器,在遵循MVC模式的Web项目中,经常出现|models|模型,在遵循MVC模式的Web项目中,经常出现|views|视图,在遵循MVC模式的Web项目中,经常出现|db|数据库相关文件|demo/example|相关示例代码|misc|其他杂项|include|头文件所在目录,c/c+项目

3、中常见|out/build|编译结果输出目录|third_party/vender|第三方库|install|安装所需的相关文件|# 5.1.2. 包名与文件名在软件体系中,包(Package)是一个很重要的概念,与模块(Module)类似,但是又有所区别。一个项目,在初始设计时,就需要做模块划分,每一个大小合适的模块,往往就可以作为一个开发工作单元,分配给某个开发者完成。当然,对于那种大型的、复杂的项目,还需对模块做进一步的细分,比如:子模块(Sub Module)。而包(Package),则往往具有一定的可重用性。我们可以认为,一个模块,开源出去未必会有人来用。而一个设计良好的包,本身就可

4、以作为一个开源项目,放出去给被人使用。因此,从更加有利于软件开发的协作的角度来说,合理的包命名,就变得非常重要。越是现代的开源项目,越是懂得不必一切从零开始搭建,所以,我们常常会发现,一个开源项目,他们自己会开发一组Package,同时也依赖一批别人开发的Package。在静态理解项目时,了解一个项目项目有哪些包,以及依赖哪些包,就非常重要。举例之一:rails是一个著名的ruby开源项目。我们访问它的github主页(https:/github/rails/rails),就可以看到这个项目的源代码结构。* 首先需要选择查看某一个稳定版本,比如3.2版 * https:/github/rail

5、s/rails/tree/3-2-stable* 然后阅读install.rb文件 * https:/github/rails/rails/blob/3-2-stable/install.rb* 我们可以看到的内容,主要包含两大部分: * 编译rails的依赖包:activesupport、activemodel、activerecord、activeresource、actionpack、actionmailer、railties。这些都是rails项目自己开发的包 * 然后再编译rails本身* rails本身的包描述文件是:rails.gemspec * https:/github/ra

6、ils/rails/blob/3-2-stable/rails.gemspec* 通过阅读rails.gemspec,我们可以了解到,rails这个项目,依赖的包还包括:bundler、sprockets-rails。 * 事实上,通过阅读activesupport等一系列包的.gemspec文件,我们还会发现更多的外部依赖包。不同的项目,描述包文件,以及包依赖关系,有各种不同的格式。需要一一分别学习。这里就不再详细解说了。在一个开源项目中,代码当然是由一个一个的源代码文件组成的。通过查看文件名,往往可以了解一个文件的大概内容。例如:* errors.rb,通常会与出错处理有关* i18n.r

7、b,通常会与国际化有关* logger.rb,通常会与日志有关* json目录下的两个文件decoding.rb和encoding.rb,自然是JSON格式的编解码相关代码通常,要迅速的辨认出一个文件名的含义,与领域知识大有关系。例如:http.rb,通常会是处理http协议相关。而request和response,则通常是网络协议中的请求与响应相关的处理代码。对于这些单词的熟悉程度,决定了我们阅读与理解代码的迅捷程度。# 5.1.3. 类名、函数名与变量名java是一门很讲究规范的语言,所以他的每一个类,就会对应一个同名的.java文件(内部类除外)。这使得我们寻找类所在的源文件,变得非常简

8、单。当然,这样会造成源文件数量的增加,也许会有人不喜欢。不同的语言,对于命名有其自己的规范,我们可以做一个列表,来简单列出这些规范。|语言|包/命名空间命名|类命名|函数/方法命名|常量命名|变量命名|Java|domainname.package 全部都是小写的单词,以.区隔|ThisClassName 每个单词都以大写字母开头|theMethodName 第一个单词以小写字母开头|THE_VALUE 全部大写,单词以下划线分隔|theValue 与函数名一致|C#|DomainName.Package 每个单词都以大写字母开头,以.区隔|ThisClassName 每个单词都以大写字母开头

9、|TheMethondName 与类名一致|THE_VALUE 全部大写,单词以下划线分隔|TheValue 与类名一致|PHP|domainname.package 全部都是小写的单词,以.区隔|ThisClassName 每个单词都以大写字母开头|theMethodName 第一个单词以小写字母开头|$THE_VALUE 全部大写,单词以下划线分隔|$theValue 与函数名一致|C/C+|std:hex 全部小写,以:区隔|CThisClassName 以大写C开头,后续是大写字母开头的单词|TheMethodName 每个单词以大写字母开头|nMAX_VALUE 特别会引入前缀的概念

10、,例如:n代表整形、b代表布尔型、c代表字符型等等|nTheValue 与常量类似,单词区分大小写|Delphi|MyUnit.Unit2 遵循Pascal命名法:一个名字里如果包含多个单词,每个单词的首字母都要大写,以.区隔|TThisClassName 以大写T开头,后续是大写字母开头的单词|TheMethodName 每个单词以大写字母开头|castMaxValue 特别会引入前缀的概念,例如:i代表整形、b代表布尔型、c代表字符型等等,cast代表常量|iTheValue 与常量类似,单词区分大小写|Ruby|Module:SubModule 每个单词以大写开头,以:区隔|ThisCl

11、assName 每个单词都以大写字母开头|the_method_name 全小写单词,以下划线分隔,!?有特定的含义|MAX_VALUE 全大写单词,以下划线分隔|the_value 全小写单词,以下划线分隔|Python|mod_submod 全部小写,以_区隔|ThisClassName 每个单词都以大写字母开头|the_method_name/theMethodName 全小写单词,以下划线分隔,也可以类似Java的命名,私有函数以双下划线开头|MAX_VALUE 全大写,以下划线分隔|the_value 全小写,以下划线分隔|JavaScript|无|ThisClassName 每个单

12、词都以大写字母开头|thePrivateMethod/ThePublicMethod 私有函数小写字母开头,公有函数以大写字母开头|MAX_VALUE 全大写,下划线分隔|theValue 小写字母开头,私有变量,加下划线|这是一个非常粗略,挂一漏万的表格,详细的命名规范,请参考各种具体语言的命名规范文档。# 5.1.4. 注释与Readme很多时候,开源项目代码里的注释,会给你带来误导。或者会让人不知所云,或者只是写给自己看到TODO,或者代码改了,注释忘记改。种种原因,因此我强烈的不建议过于重视注释。但是,在业内有一种流派,非常重视注释,而且信奉从源代码的注释,就可以直接生成项目的开发文档

13、。比如JavaDoc这样的东西,在java的开 源项目里,简直用到泛滥,也造成了java的很多项目,注释数量比代码的数量还要多。而且,格式规范,千篇一律(为了生成Document),真正有意义 的注释内容,少之又少。纯粹是干扰阅读。很多时候,我都建议阅读代码,就真的去读代码。然后试着从类名、方法名、变量名中,大致“猜出”代码的意义。然后再实际的将代码运行起来,看看执行过程中,这些代码是如何工作的。总之,不到万不得已,不要先看注释。虽然我个人对于注释,相当的不重视,但是却非常认同Readme的价值。令我倍感欣慰的是,Github的创立者,也完全赞成这一点。他们将一个 项目的首页,直接规定为“代码

14、展示+Readme”,也就强迫所有在Github上安家的开源项目,将更多的精力,投注到Readme的撰写中去。这样形 成的良性循环,使得我们可以乐观的预期:越来越多的开源软件,将会越来越重视项目根目录下的Readme文件的价值,将一个项目最为重要的内容,以最为精 炼的方式,在Readme中,以结构良好的方式,展现出来。因此,首先阅读Readme,对于了解一个开源项目,是一个非常好的选择。# 5.1.5. UML图UML是一种软件建模语言,全称为:统一建模语言(UML,Unified Modeling Language)。非常巧合的是,在打算写这一小节的今天,蔡学庸 发了两条微博: 有时候我会一

15、边读源码,一边将我的理解画成图。这是我最近读源码画的图,还没有美化处理。 阅读源代码时,将代码顺手图像化,有助于我思考与记忆。位置、色彩、形状,这些都是我将源代码图像化时会采用的手段。我非常期待,他能够就这个问题,谈到更多的心得。在我看来,在阅读源代码的时候,不断记录,在脑海里形成整个项目的全景图像,是非常有帮助的。关于UML的定义,可以参考维基百科: UML(http:/zh.wikipedia.org/wiki/UML),以下引用一段: 统一建模语言(UML,Unified Modeling Language)是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和

16、编写一个正在开发的、面向对象的、软件密集系统的 制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。 UML集成了Booch,OMT和面向对象软件工程的概念,将这些方法融合为单一的,通用的,并且可以广泛使用的建模语言。UML打算成为可以对并发和分布式系统的标准建模语言。 UML 并不是一个工业标准,但在Object Management Group的主持和资助下,UML正在逐渐成为工业标准。OMG 之前曾经呼吁业界向其提供有关对象导向的理论及实现的方法,以便制作一个严谨的软件建模语言(Software Modelin

17、g Language)。 有很多业界的领袖亦真诚地回应OMG,帮助她建立一个业界标准。在UML系统开发中有三个主要的模型:* *功能模型*: 从用户的角度展示系统的功能,包括用例图。* *对象模型*: 采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类图。* *动态模型*: 展现系统的内部行为。包括序列图,活动图,状态图。在学习开源软件时如何使用UML,有以下一些经验和忠告:* 不用使用工具,自动化的生成UML。自己手绘或者用Umbrello这样的开源工具自己绘制,将大大提高阅读并理解代码的能力。* 首先建立对象的静态模型,也就是先画“类图”。* 在UML规范之外,可以加一些辅助自己

18、记忆的符号,这个没有一定的规矩,方便好记就行。* 其次在动态理解的过程中,对关键的执行路径,画出时序图(Sequence Diagram),将有助于深入理解项目的执行过程。* 对于非面向对象的软件项目,可以参照类图与组件图的模式,画出模块图。也有助于加深理解。* UML本身有越来越复杂,越来越学术化的倾向,要适可而止。# 5.1.6. 外部文档开源项目的文档水平,有如下几个层次:* 没有文档(比这个更糟糕的,是有一些错漏的,长时间没有更新的垃圾文档)* 有一个根据代码注释自动生成的XXDoc,通常这样的文档,价值很低。还不如直接去看代码。* 有一个简单的综述性质的文档,至少告诉你一个项目的大概

19、。* 有完整的项目文档,这样的项目已经非常罕见了。* 有各国志愿者帮助翻译的多语言文档。这样的项目,通常已经是世界一流的项目了。* 有专门的文档、博客、甚至图书,XX项目源码解读之类。一般只有Linux、MySQL这样的项目,才有这样的待遇吧。一般来说,外部文档的可信度并不高,而且往往过时。不到走投无路,我不建议找外部文档来帮助理解。当然,一些太复杂的项目,作为入门导引,看看也无妨。ZoomQuiet补充:可以借用 CMMI 的几个层次来类比出文档的层次:* 0级: 无文档* 1级: 号称有文档* 2级: 有可用文档* 3级: 文档完备* 4级: 文档丰富* 5级: 文档开放,可持续完善# 5

20、.2. 动态理解所谓动态理解,就是让项目运行起来,在运行项目的过程中,理解一个项目是如何运行的。(这个有点像绕口令了。)# 5.2.1. 输出日志所谓日志,在软件领域,通常是指程序运行的一种记录。开发者与维护人员,可以通过分析日志,了解程序的运行状况。日志输出的数量多寡,可以分为以下几种:* 完全没有输出(这不是一种好的做法)* 有出错与崩溃时的输出日志(主要用于排除故障)* 打开某个参数配置的开关,例如将日志级别修改为debug,将会输出更多的日志信息(主要用于调试程序)* 为了理解特定的片段,直接修改代码,增加更多的日志输出,甚至将代码执行过程中的所有相关变量,全都输出出来。(用于查找疑难

21、杂症,深入理解源代码等目的。)ZoomQuiet补充:同前,应该使用相同的递进分析层次* 0级: 无日志* 1级: 号称有日志* 2级: 有可用日志* 3级: 日志级别完备* 4级: 日志粒度可调节* 5级: 有通用日志服务,可集中分析一个比较完善的开源项目,通常会输出一些日志,如果你搜索整个项目的源代码,都找不到(log,logger,logging)这样的关键字,那就比较糟糕了。通过修改源代码,以增加更多的日志输出,是我们常用的一种手段,最好是能够找到项目中可供参考的输出日志的办法,照着那个例子来改写。如果实在找 不到,或者调用存在一些陷阱,也可以自己纯粹手工的添加日志输出代码。简单的举一

22、个ruby的例子,下面的这一行代码,就可以输出一段内容到日志文件里去 了。 File.open(temp.log,a) |f| f.puts(log info) 输出日志,能够解决大多数情况下的理解需求,唯一可能会有陷阱的,则是*多线程程序输出的日志*,因为每次输出的内容可能次序不一致,因此需要特别小心。# 5.2.2. 设置断点与单步跟踪IDE有一个重要的好处,就是可以帮助程序员调试程序。在一个图形化界面里,跟踪调试程序,有着纯文字界面难以比拟的便利性。!(images/debug-NetBeans-IDE-7.0.png)Netbeans IDE 7.0 调试PHP的程序片段在一个宽屏的显

23、示器里,同时显示源代码树、对象结构、当前执行到的代码行、当前的各种变量值、调用序列、各个线程、输出内容等等等等,还是很爽的。当然,要使得IDE能够调试一个开源项目,还是有很多琐碎的事情需要处理。例如:* 如何在IDE中打开一个项目* 如何在IDE中配置一个项目的依赖项* 如何在IDE中编译并运行一个项目* 如何在IDE中设置断点这些如何,因语言、平台、IDE、版本、具体项目的不同,而有所区别。这里没法给出一个周到全面的解决方案,但是可以给一些搜索方面的建议:* 假设要在Netbeans 7中打开一个开源的Java项目,可以搜索“how to open java project in netbe

24、ans 7”,然后我们可以找到一些文档: * http:/netbeans.org/kb/docs/java/project-setup.html * http:/stackoverflow/questions/4382619/how-can-i-open-non-netbeans-java-project-using-netbeans当然,一定会有各种让人挠头的问题,各位多多尝试吧。另外推荐一本书,是张银奎写的软件调试,大部头。但是的确是一本好书!http:/book.douban/subject/3088353/# 5.2.3. 抛出异常有很多种语言,都支持异常处理,以及手动抛出异常。在特

25、定的位置,将整个调用序列打印出来,可以方便我们快速的找到整个项目,是从何处开始,又是如何一层一层的调用,最终到达我们设置抛出异常的位置的。在Java语言中,我们可以这么写:(new Exception().printStackTrace();在PHP语言中,我们可以直接调用函数:debug_backtrace();或者debug_print_backtrace();在Ruby语言中,我们可以这么写: begin 1/0 rescue = exception puts exception.backtrace end其他种类的语言,建议各位可以自行Google。在调用了类似的函数之后,我们可以或者

26、类似如下这样的输出: java.lang.Exception at org.jruby.lexer.yacc.LexerSource.getSource(LexerSource.java:147) at org.jruby.parser.Parser.parse(Parser.java:122) at org.jruby.Ruby.parseFile(Ruby.java:1965) at org.jruby.Ruby.parseFile(Ruby.java:1969) at org.jruby.Ruby.parseFromMain(Ruby.java:364) at org.jruby.Rub

27、y.runFromMain(Ruby.java:327) at org.jruby.Main.run(Main.java:214) at org.jruby.Main.run(Main.java:100) at org.jruby.Main.main(Main.java:84) 以上信息,清楚的现实了某某源文件的某某行,发生了一个调用,进而在下一个源文件中的某个函数,被调用了。于是,我们就可以从抛出异常的代码,开始逐级回溯,阅读相应的代码片段。# 5.2.4. 修改代码,破坏性尝试在初步理解了项目代码之后,可以尝试做一些简单的修改,看看会发生什么。* 编译错误静态类型的语言,在这方面有更多优势

28、,通过编译时给出的错误提示,你可以知道自己改坏了什么,以及为什么它被改坏了。比较令人头痛的,是用了各种复杂的模板语法的C+语言,这时候编译器可能会给出一些令人莫名其妙的报错信息,那你就抓瞎了。不过,开源初学者,一上手就去啃复杂的C+代码,也很难说是明智的选择。* 运行时报错与编译期报错类似,你也可以通过阅读一堆一堆的报错信息,了解代码是如何运作的,以及为什么原来不报错,现在就开始报错了。不过,触发运行时报错,可能会有些困难,这涉及到你修改的代码,是处于主线还是支线位置,以及有多少相关功能,依赖于你所修改的代码。* 功能失效可以尝试注释掉一些代码,看看会发生什么事情,比如某个功能按钮失灵甚至消失

29、。当然,对于JavaScript代码,我们常常会喜欢在某些位置加上alert,看看什么时候会弹出一个消息提示框,缺什么事都没有完成。* 走走捷径我们常常会看到的一类代码,是长期发展完善后的产物。从接收消息,要处理某某事件开始,到真正去完成某某功能,其间还做了很多的额外工作,比如数据校验,纪录日志,触发其他消息等等,将这些代码全部注释掉,大多数功能都还是正常的,但是,会出各种意外,可以进一步做出各种尝试。(详见5.3. 主线与支线)# 5.2.5. 工具有很多辅助代码阅读工具,简单的介绍一些* IDE类既然是IDE,自然大多数都已经集成了相当不错的代码阅读功能,索引,反查,标注,自由跳转,通常都

30、应有尽有。比较好的IDE,有Eclipse、Netbeans、IntelliJ IDEA、Visual Studio(Express)等等,各种面向专门语言的IDE还有很多,可以自行在Google搜索“Best XXX IDE”。进阶阅读:18 个最佳代码编辑器/IDE推荐(http:/iteye/news/24235)* 传统神器超牛插件所谓传统神器,自然是指Emacs与VIM,这两款神器不能简单的以是否IDE来划分。他们都带有众多的插件,可以扩展出惊人的灵活性。推荐阅读两篇文章:Emacs和它的朋友们阅读源代码篇(http:/baohaojun.github/reading-source-

31、code-cn)自己动手定制一个高效阅读源代码的vim(http:/zqwt.012.blog.163/blog/static/1204468420114194264789/)* 专业工具专业工具,通常也是由商业公司开发的收费软件,人家要挣钱,自然也要有拿得出手的好东西。这里推荐两款软件,更多介绍,请自行搜索相关介绍与教程:* Understand(http:/scitools/index.php)* source insight(http:/sourceinsight/)* 软件工程相关工具所谓软件工程的相关工具,主要是一些与面向对象概念相关的UML工具,比如IBM的Rational Rose、Sybase的Power Desinger、还有Borland的Together,都是大公司出品的一些大家伙。可以将面向对象语言(主要是Java)的项目,转换输出成为UML的各种图,有一定的参考价值,玩玩也不错。# 5.3. 主线与支线一个开源项目,我们总可以从中找到主要的功能与次要的、辅助的功能。一个系统从启动开始,到完成最核心的功能、任务,最后成功结束,就是一条主

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1