JS调用链

函数调用

JS中函数之间存在创建,调用关系,这种关系是强关联关系。

函数调用时操作的数据,除了入参,还有其作用域链上能访问的数据。函数的作用域是其定义的地方。

不同的函数可能经作用域链访问和操作同一个数据,他们之间的关系是弱关联关系。

各种不同的强关联、弱关联关系是程序微观执行时的一种形态。
对象在一定程度上也可以大致抽象认为是函数,是一组函数,拥有相同的上下文,并且自身可维持状态。

调用链

函数之间通过调用关系形成一条链,称之为调用链。函数是调用链上的一个环节,一个点。

调用链有头有尾执行从前往后,可以用一条线来表示,为简化用一条直线表示。

调用链的头和尾是相对的,取决我们的观察需要。一条链可以一分为二分别进行分析。

一般调用链的头是从系统的交互界面或边界接口开始的。

依赖链和调用链是软件静态结构的一种表现,而调用链执行起来,则完成了软件的功能。

不同的调用链,都包含同一个函数,那么就认为它们相交,交点就是这个函数。

程序当中,有许多调用链,并且他们可能多次相交。

调用链不管相交与否,他们中任何两个函数都拥有相同的依赖,那么就是隐形相交。

调用链存在分叉的情况,主链可产生多个次(支)链。主链可能存在多个分叉点。而次链又可以产生次次链。

调用链总体可以看作是一种树形结构,而各种交点就是树中的结点。很多时候情况比较复杂,甚至形成了图的结构。

调用链的特性

对于软件,微观上每一条调用链执行正常,宏观上软件功能才能正常。

某条调用链上每一点运算都是正确的,那么该条调用链运行就是正确的。

函数调用或调用链运行符合期望,称之为正确性

调用链中的一点发生故障(计算错误,抛异常等),该点以后链的正确性被破坏。

链交叉点及以前的地方出现故障,该点及以后的链正确性被破坏。

对于主次链,分叉点前出现故障,该点及以后所有次链正确性被破坏。

可以理解,链上的点的正确性依赖前一个点的正确性。或者是说,调用链的正确性向前依赖

调用链存在相交,导致计算的非正确性具有传染性。A链的存在bug,会导致相交的B链也可能运行出错。

相交越多,传染性越强。耦合性就是具体的体现。

随着需求迭代,调用链会发生改变,会增长缩短断裂等。手抖了也会导致链的改变。

调用链的易变性,导致我们常常遭遇莫名其妙bug的困扰。

调用链的易变性,也让我们可以随心所欲的修改链,删减链,嫁接链来实现我们想要功能。

开发一个功能,甚至可以简单的认为是加一条链就好了。

调用链链接的地方就是发生函数调用的地方,可以称为截面。

在截面上可以进行数据的检查,过滤,改造等操作。截面也随时随地可以嫁接或生成新的链。

调用链并不是无脑的调用,调用链上传递了信息、数据或逻辑。数据不会无缘无故从A模块到B模块,必须通过调用链传递过去。

调用链执行形成的调用流可形成管道作用运输信息流、数据流、逻辑流。

现在流行的MVVM框架,其维护的数据不会自动渲染成视图,其必依赖于一条调用链来达成。而这个调用链的源头往往就是监听数据的改变。

调用链每一个环节可能维持状态,导致调用链整体体现的状态有不确定性。不确定性导致调用链每从头到位执行一次,其表现的功能是不一样的。

调用链形成后,其中的每一个环节都不能轻易改变,否则该点之后链的正确性会受到影响。

调用链往前越僵化,往后越灵活,表现出头重脚轻的特性。

调用链的执行是向后进行的,但是走到链的末端,会逐个向前返回调用结果,直到链的开头。调用链有种回归的特性。

利用回归特性,想要任何的数据,可以通过一个调用链去获取。递归调用也是利用了这个特性。

基于调用链分析的实践建议

1.调用链之间没有交叉/分叉最好,这样链执行的正确性只和自己有关,满足低耦合的特征。

如果一定交叉/分叉,那么一方面减少交叉/分叉点数量,一方面将交叉/分叉点往后移,减少影响范围。

相对的,经常变化的逻辑,放在链的末端,而链的前端应当非常健壮。

调用链承载逻辑链,业务链。次链的一部分逻辑写在主链里,那么如果这部分逻辑发生故障或变更,其他次链的正确性就会受到影响。

所以主链避免处理次链的具体逻辑,最好充当管道的形象,传递调用流和无特定意图的数据。

具体的逻辑,放在次链里处理,满足高内聚的特征。可以称之为重心后移

许多开发框架,经常充当生成和触发主链的角色,而我们实现的逻辑放在主链的次链中。这个交叉的地方,常被称之为钩子

2.调用链最好是无状态的,这样每次运行的结果都是一致的。

为了降低非正确性概率,希望更多使用纯函数和无副作用函数来确保程序的正确性,减少链隐性相交,减少状态带来的不确定性。

如果要引入状态,那么这些状态要么需要进行集中管理,要么就放在链的末端,降低风险。

说到副作用,也是很有用的一种技术,如果使用得当可以很好的起到关注点分离,进而降低耦合的作用。

3.被依赖意味着更多的责任。组件、对象、函数,被依赖了,那么随着迭代,需要变化时就要考虑到影响范围。

组件、对象、函数需要遵守单一职责原则,最小知识原则,接口隔离原则等。水平扩展式的变化比较好。

功能增强式的变化最好是做到向前兼容,并且引入版本管理,即使遭遇断崖式的变化,也可以通过版本控制住影响。

4.应当使用开发框架或定义机制。开发框架内有良好的结构,开发框架承载了最根本的健壮性要求。

没有开发框架,那么我们需要定义一套系统结构或机制来承载系统健壮性要求,特别是应对多人协作和快速迭代。

  

 (持续完善中,仅供交流,不喜勿喷~o~)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值