如何高效地查看开源项目源码?


我们为什么要看源码?

这个小标题好像有点扯淡,不过我感觉还是有必要聊一聊。
最近搞 Blazor,手边常备 AspNetCore 源码,遇到问题了就翻源码。
然后有同样关注 Blazor 的同学会一起讨论一些问题,我知道的问题会直接分享,我不知道的问题,我就,甩一句,“看源码”
然后有的同学炸了,说,“不是每个人都可以像你一样看源码,源码不是每个人都能看的,不是每个人都想看源码”
当然原话不是这样,后两句是我添油加醋的,不过这两句想必是大部分同学的心声,心里害怕看源码,觉得看源码都是大神才会看的。

看源码的正确姿势

st=>start: 遇到问题
search=>operation: 百度谷歌
isOk=>condition: 能解决吗?
donotusecode=>end: 好了你可以不用继续看了
usecode=>end: 分析源码解决
st->search->isOk
isOk(yes)->donotusecode
isOk(no)->usecode

看源码的错误姿势

st=>start: 听说看源码能学到很多东西,能通过面试,能XXXXX
usecode=>end: 看源码
st->usecode

感觉第二个流程图像是在扯犊子,其实第二个图也并非完全错误,只是在强调你不能为了看而看,你要带着问题去看,但如果这样的话,那其实又变成了第一张流程图了

看源码的方法

很多同学在满足第一个流程图的条件之后,可能看源码仍然感觉累,没有头绪,这是没掌握看源码的技巧,可能存在以下几种情况

  • 拿着 github 在线看源码,这和拿记事本看源码没好到哪去
  • 真的就拿着记事本看源码,或者拿着 VSCode 看源码(我不是黑它)
  • 不擅于使用 VS 的相关功能

看源码一定先编译源码

不用编译直接打开 VS 一把梭,不是很好吗?
不好,确实是可以打开的,但是这个时候往往因为没有编译过导致 VS 的很多功能不可用,例如转到定义、查找引用。
对我而言,编译源码是个艰难的过程,看源码反而简单。特别是 AspNetCore 的源码,编译起来要了半条命。
关于怎么编译,每个开源项目都不一样,有的项目简单,打开 VS 直接就能编译,但是像 AspNetCore 这种,必须严格按照官方给的编译步骤文档,还得保证网络畅通,编译过程中很容易被劝退。

五大板斧不可少

有很多同学看源码的过程让我比较着急,咋看的呢?
CTRL+F,输入搜索词,全解决方案搜索,不管是怎样的情况全是这样搞,解决方案比较大的话一搜一大堆出来。
也许只是我周围的同学是这样的吧。
我看源码的过程中常使用这些方法

  • 转到定义,F12
  • 转到实现,CTRL + F12
  • 查找引用
  • 调用堆栈
  • 解决方案管理器搜索

这五大板斧中,除了调用堆栈,其他的几乎都是静态分析代码的必备方法,调用堆栈一般属于动态分析代码的办法。
这五大板斧用好了,只要源码的变量命名不要太坑爹,基本上是不需要看注释的,我看开源项目的源码从来不看注释,开源项目的源码的命名一般都是比较好的。

下面我将举例来分享我看源码的过程,把上面这几个方法用上

问题实例:怎么根据路由获取对应的组件?

这是我在编写 BlazAdmin 时遇到的问题,我需要根据当前路由得到这个路由对应的那个组件,然后做一些操作,我甚至不知道如何搜索,因为关键词不好搞,随便搜了几个也没找到答案。

下面开始分享我针对这个问题的解决思路,下载编译 AspNetCore 源码的步骤我就不写了

第一个问题,从哪儿开始?

万事开头难,刚开始看源码更难,无头苍蝇的感觉。
我们的需求是,怎么根据路由获取对应的组件,这里面有两个关键词,一个是路由,一个是组件
我们换位思考一下,假如由我们来开发这个功能,我们会写哪两个类?
答案应当很明显,RouterComponent,当然也许不是这么命名的,都有可能。但好像知道这两个名字了还是没啥用?根本问题在于 AspNetCore 解决方案太多,我们压根不知道应该打开哪个解决方案,也就无从搜索这两个类名。
我的办法是,也许这两个类我们是可以直接使用的,那么如果可以直接用的话,我们应该可以在代码的任意地方调用这两个类,那么我们就试试。
在我们自己项目的 Program.cs 文件中,随便找个地方,我们首先尝试 Router 关键字。

好像有戏,我们已经看到命名空间了,那么根据这个命名空间,我们尝试找到对应的解决方案,这个命名空间的关键词是什么呢?Microsoft?AspNetCore?这两个关键词太大众化了,那么只剩下两个,Components 和 Routing,我们一个一个来


没啥好说的,既然找到了,管它是不是,先打开看看再说。

我们直接在解决方案管理器中搜索这 Router 这个类。

我们的入口点已经显而易见了

第二个问题,这个类是如何找到 Component 的?

这个类中有这么些方法

根据方法猜功能,没错,看源码全靠猜,猜错了换条路继续

OnAfterRenderAsync 这个应该不是
OnLocationChanged 这里面都有些啥?

这里面调用了 Refresh 方法,F12 跟进去

开始发晕了,咋这么多呢,而且还不明显,我们一行行看,一行行猜
看第五第六行,这两行有点意思,跟当前路由有关,也许是我们想要的
F12 进 RouteContext,看看里面有啥

好吧啥也没有,我们继续看第六行,F12 进 Route 方法

越来越像了,Match 方法里面又是什么呢?F12 进去

这个方法中看起来也不像那么回事,不过还是有点有用信息,最后一句代码将 Handler 赋值了一下,但问题是 Handler 是啥?看这命名有点像当前路由的处理器,那么这个处理器可能就是我们要找的 Component,从构造方法中可以看出这个 Handler 是由构造方法传过来的,构造方法可以看到还有一个引用,意味着有地方在显示调用,那么我们通过查找引用跳过去看看

看来这就是我们要找的了,越来越近了,这里应该是在分析路由模板,那么路由模板应该是调用这个方法的地方传过来的,再次查找引用跳过去

两个地方在调,咋办?明显可以看出第一个地方是单元测试调的,所以其实只有第二个地方在调

Template 就是路由的模板,而这个模板是由 RouteAttribute 特性来得到的,而这个特性是标记在每一个组件的 Type 上的,也就是说,只要获取所有组件的 Type,就可以拿到所有组件对应的路由,这样一来,我的问题解决了

总结

  • 大胆猜测,小心求证
  • 换位思考,如果是我,我会怎么命名,这个常用于寻找分析入口点
  • 英语别太差,不过一般来说你坚持看源码英语会提升的
  • 不要 CTRL + F,不要 CTRL + F,不要 CTRL + F,多用 F12,查找引用
  • 在某些特殊情况下,例如别人都是通过反射调用的,那么就只能 CTRL + F 了

可以看到,解决这个问题的过程几乎全是靠猜,猜错了就回过头去猜下一个,猜对了那就对了。所以如果说某个开源项目的命名太糟糕,那就确实不好找了。当你看源码看多了之后,你就不需要猜了,因为你已经知道命名是啥了。

在这个示例中,我们没有使用转到实现,因为其实这个示例所涉及到的代码还是简单的,没有涉及到太多的多态,因此不需要转到实现。如果涉及到多态,那么过程会复杂很多,因为要看的路径太多,但总归是能看完的,相比用谷歌去搜索半天压根就没有头绪,花点时间猜源码还是值的。

原文地址:https://www.cnblogs.com/wzxinchen/p/12103243.html

时间: 2024-08-03 06:35:19

如何高效地查看开源项目源码?的相关文章

分析开源项目源码,我们该如何入手分析?(授人以渔)

1 前言 本文接上篇文章跟大家聊聊我们为什么要学习源码?学习源码对我们有用吗?,那么本篇文章再继续跟小伙伴们聊聊源码这个话题. 在工作之余开始写SpringBoot源码分析专栏前,跟小伙伴们聊聊"分析开源项目源码,我们该如何入手分析?"这个话题,我们就随便扯皮,反正是跟小伙伴们一起学习交流,没必要太正式. 小伙伴们看完本文后,若有自己的源码阅读心得可以在下面进行评论或私聊我进行分享,让我从小伙伴们身上GET多点源码阅读的一些技巧,嘿嘿. 2 学习开源框架源码到底难不难? 那么,先跟小伙

Android 开源项目源码解析(第二期)

Android 开源项目源码解析(第二期) 阅读目录 android-Ultra-Pull-To-Refresh 源码解析 DynamicLoadApk 源码解析 NineOldAnimations 源码解析 SlidingMenu 源码解析 Cling 源码解析 BaseAdapterHelper 源码分析 Side Menu.Android 源码解析 DiscreteSeekBar 源码解析 CalendarListView 源码解析 PagerSlidingTabStrip 源码解析 公共

Android 开源项目源码分析第一期正式发布

由 Trinea 发起.几十名 Android 开发者参与的Android 开源项目源码分析第一期正式发布. 从简介.总体设计.流程图.详细设计全方面分析开源库源码,第一期包括 10 个著名开源库及 5 个公共技术点的全面介绍. 分析文档 作者 Volley 源码解析 grumoon Universal Image Loader 源码分析 huxian99 Dagger 源码解析 扔物线 EventBus 源码解析 Trinea xUtils 源码解析 Caij ViewPagerindicat

汇聚各种android开源项目源码分类总汇-IT蓝豹

android开源项目源码分类总汇: 1.完整源码 (29) 2.开发框架 (14) 3.弹出视图 (Popup View) (6) 4.引导页 (Intro&Guide View) (6) 5.手势交互 (Gesture) (13) 6.图表 (Chart) (9) 7.视图切换 (View Transition)(14) 8.视图布局 (View Layout) (14) 9.视图效果 (View Effects)(23) 10.动画 (Animation) (34) 11.文本显示 (Te

【转】Java开源项目源码阅读方法及二次开发方法

一直以来,都想要阅读某些Java开源项目的源代码,甚至想要修改某些代码,实现对开源项目进行二次开发的目的.但总是不知从何入手,直接将开源项目的源代码导入Eclipse,总是会报很多错误,而无法编译.可以直接通过Eclipse打开开源项目的源代码,至少能够达到可视化源码阅读.源码导航的目的,还是能在一定程度上解决源码阅读不爽的问题,因为直接打开并没有改变源文件项目的目录结果,对于修改过后的代码,可以通过命令行找到源文件项目目录,并使用mvn或者ant对项目进行编译,再查看修改后的项目是否正确. 由

Android 开源项目源码解析之DynamicLoadApk 源码解析

1. 功能介绍 1.1 简介 DynamicLoadApk 是一个开源的 Android 插件化框架. 插件化的优点包括:(1) 模块解耦,(2) 动态升级,(3) 高效并行开发(编译速度更快) (4) 按需加载,内存占用更低等等. DynamicLoadApk 提供了 3 种开发方式,让开发者在无需理解其工作原理的情况下快速的集成插件化功能. 宿主程序与插件完全独立 宿主程序开放部分接口供插件与之通信 宿主程序耦合插件的部分业务逻辑 三种开发模式都可以在 demo 中看到. 1.2 核心概念

常用开源项目源码地址

[jetty] git://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git [spring-framework] https://github.com/sprin

App开源分享-在路上项目源码

App开源分享-在路上项目源码 在路上是一款旅游型的APP,是集旅游旅游目的地攻略指南,可以自动定位到城市,景点,餐馆,酒店,还可以分享旅游经验,与参与者互动.架构合理,有详细的注解.很好的学习材料. 下载地址:http://www.devstore.cn/code/info/905.html 运行截图:    

2016年最牛逼的分类Android项目源码免费一次性打包下载!

之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年开始不断整理源码区和其他网站上的安卓例子源码,目前总共有810套左右,根据实现的功能被我分成了100多个类,总共接近2.5G,还在不断更新.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是我一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不要一分钱!最看不起那些挂羊头卖狗的)你可以在本帖里面按Ctrl+F查找你需要的关键字,