上一篇我们通过抽象模型梳理了核心流程。
本篇是《如何高效阅读源码》专题的第九篇,我们来通过绘图加深核心流程的理解,同时将抽象模型和核心流程与概念模型进行整合,以得到一个更具象化的流程。
本篇主要内容:
-
为什么要绘图?
-
绘制核心流程图
-
整合抽象模型和概念模型
为什么要绘图?
上一篇我们通过抽象模型梳理了核心流程。现在回想一下,你还能记得多少内容?!是不是只记得个大概?甚至一点都不记得了?!
我们再往前推一点,在梳理核心流程之前,我们先基于核心类梳理了一个抽象模型,现在回想一下,你还能记得这个抽象模型吗?是不是还能隐约记得有TestClass、FrameworkField、FrameworkMethod以及FrameworkMember?然后是否能回想起它们的结构?FrameworkField和FrameworkMethod是FrameworkMember的子类,TestClass构建了FrameworkField和FrameworkMethod。
根据美国哈佛商学院有关研究人员的分析资料表明,人的大脑每天通过各个感官接受外部信息的比例差异很大:味觉最少只有1%,触觉次之1.5%,嗅觉第三为3.5%,听觉第四为11%,而视觉则高达83%。
所以,花点时间画一些图辅助记忆是非常有必要的。不但可以加深我们的理解,也便于存档,方便以后需要时,能快速的唤起我们的记忆。也就是说,即使你忘记了梳理的内容,你也能通过绘制的模型图和流程图回忆起流程,否则你需要花费更多的时间来再看一遍文章。
绘制核心流程图
在面向对象里,一般通过时序图来描述对象之间的交互关系,但是时序图在这里相对太细化了,复杂的时序图阅读起来也不方便,同时也不方便和前面的概念模型进行整合。所以我们不使用时序图,而直接基于抽象模型来手动绘制一个通信图(非标准通信图,主要是为了示意出流程)。
通信图在UML中也称为协作图,展示了合作对象间如何通过发送和接收消息进行动态的交互。
首先我们删除抽象模型中的依赖关系,只留下接口和类。如下图所示:
接着,我们加入前面梳理出来的核心方法:
-
TestClass中的构造方法,scanAnnotatedmembers方法、collectAnnotatedFieldValues方法和collectAnnotatedMethodValues方法
-
FrameworkMember的handlePossibleBridgeMethod方法
-
FrameworkField的get方法
-
FrameworkMethod的invokeExplosively
最后,结合方法的执行流程,将各个类通过线条连接起来。
抽象模型和概念模型整合
注意上面的图,有没有发现少了点什么?从上图我们可以明确TestClass是模型的入口,但是谁去实例化TestClass呢?目前还不知道,我们先将此类称为Client,将其补充到图中。
这个Client并不属于抽象模型,所以我们可以在这里画个边界,将Client和流程模型隔离开。
现在我们再来考虑一下,这个Client可能是什么呢?
我们可以回过头来看概念模型,概念模型给出了一个完整的流程。
从这个流程里,我们来看一看,哪里可能会调用TestClass呢?一个可能的地方就是TestRunners!即
-
TestRunners通过各个Test的Class构建TestClass
-
然后调用TestClass里的collectAnnotatedMethodValues和collectAnnotatedFieldValues方法执行相关测试
-
再通过对收集到MemberValueConsumer里的结果的判定,得到Result
那么现在的概念模型可能就变成了下图这样:
这个流程正确吗?不一定,我们后面需要通过阅读源码来验证它。
总结
本文讲解了如何通过核心流程绘制出核心流程图,并将核心流程图与概念模型结合,得到一个更加具象化的概念模型。
下文将通过对扩展模块的阅读,来进一步完善这个模型。