Req-->a-->c--->b---->return (链式调用)
链式调用和我们普通的函数调用是存在差别的:函数调用,它的规则是,a-->b 对a来说,它只需要知道b的签名(函数列表和返回值),a为调用b的签名准备好相应的数据,a并不需要知道b的具体的实现细节,我们只需要知道他的接口数据。a在理论上是没有办法影响到b的。
调用连更倾向于一种设计模式上的一种处理,那么我们如何设计这个东西呢?
链式调用的时候,面临一个很麻烦的问题就是函数签名,当b、c的函数签名不一样的时候,他们如何注入进来,我们通过a、b、c的签名统一起来,只要你在配置的时候,把它放到一个列表里面,因为他们的签名完全相同,好处在于可以随时去调整a、b、c的顺序。 问题在于a、b、c他们三个函数的签名不可能完全一样。这时候我们来做一件事情,把逻辑和数据分离开来,a、b、c对于我们来说是逻辑。所有的逻辑理论上是无状态的,无状态就意味着我们可以做很多的事情诸如负载均衡之类的。因为你本身不存储状态,我把a、b、c的状态全部移除掉之后,它们只负责接收一个东西,这个东西叫做:数据容器。这个容器里面存储a、b、c所需要的所有数据,所有a、b、c只接收这么一个数据容器,把它取个名字叫context,a、b、c本身只处理逻辑,所有的状态由context来传递。
context是一个状态对象,状态对象在链式里面进行传递,这个状态对象提供来逻辑执行环境的东西,这种执行环境对前后造成了依赖。
我们把耦合从逻辑转移到上下文对象中来。上下文对象除了提供一个数据容器的作用,它还影响了链式调用后续环节的行为。
上下文从设计模式的角度和函数的区别?
考虑到数据安全,各个gorutine必须采取协作的方式去执行。
- 利用上下文可以统一a、b、c的签名,我们可以用灵活配置的方式来进行链式调用,而不是强耦合的关系
- 上下文还可以传递信号,仅仅是传递信号,而并没办法去控制这个信号的后续行为。
从数据角度来看,上下文一般具备两个特征:
- 上下文具备继承性,a、b、c的调用过程中,我在a设置了一个x=1,那么b和c都要能阻挡x=1这么一个设置,b在执行中把x修改为2,那么c读出来的x应该是2,而不是1,对于a来说,我不关心后面该干什么,当我把数据传递出去之后,它本身的工作已经完成了一半,剩下的一半就是接收返回值,去找在继承层次上离我最近的一个设置,类似于OP编程的理念。x=2只对后续环节有用,对a来说不管用,为了保证a不受污染,在上下文中,我们需要同时存储x=1和x=2这两个数据,并且要保证a看不到x=2这个数据。避免接口污染。 任何时候对于上下文的修改,都只应该是针对本地状态的,而不应该对上一级有影响,只能去向下传递。一旦c执行完,它的设置就应该失效,整个状态回述到b的执行状态,然后一级级往回走。
- 上下文可以向后续环节传递一个信号:比如取消或者超时。这个时候我们可以使用异常逻辑将代码段保护起来,异常和错误是两码事,错误是不可恢复的,异常往往是用来做逻辑跳转或者信号的接收。我们不应该把超时和取消操作带到我们的代码逻辑中去。异常可以使用信号的方式来终止正常逻辑的执行。
上下文使用的时机?
上下文在链式调用的时候使用是比较合理的
本文只是对雨痕大佬讲述的总结,致敬雨痕大佬。
家境清寒,整理不易。

网友评论