在一个框架中,许多地方都要用到上下文(Context),可以说上下文的实现是否到位,直接关系到开发的便捷性及访问效率。
什么是上下文呢?上下文可以认为是在访问者和被访问者之间进行信息传递的纽带。一般的,我们函数之间调用时通过函数参数及返回值来做做数据的传入和传出,但是,这样就会出现不同访问之间的参数都是不同的,在程序中访问的时候,这当然没有问题。但是对于框架来说,它事件不知道你要用什么方式调用,提供的函数及返回值是什么也不知道,这个时候一般来说,会提供一个上下文(Context)来提供数据传入和传出,当然,也有的人叫它数据总线。
Tiny框架是一个SOA体系,因此,肯定要涉及上下文的问题;同时,还提供了流程编排的框架,这就更离不开上下文了。
我们来描述一次请求看看数据的流转,比如:我们有一个服务原型是:String sayHello(String name);这样,在页面请求时,需要输入一个name的参数,给控制层,控制层调用远程服务来访问sayHello服务,然后返回值,并让展现层进行展现:
浏览器端输入以下url:xxx.xxx/xxx/sayHello.do?name=abc,这个时候控制层从request中读到了name的值为abc,这个时候,去调用远程服务,就要构建服务调用上下文,在服务调用上下文中放置name:abc键值对,然后调用远程服务,远程服务处理,拿到上下文,根据调用的服务读出参数,并调用sayHello服务,这个服务可能是一个流程,那么这个参数又要传给流程的上下文进行执行,执行出结果之后,又要按照原路进行返回。
说得比较啰嗦,但是还是表明了数据需要在许多个上下文之间进行流转。虽然这个过程,对于普通开发人员及使用者来说,是看不到的,但是它就在那里,这个过程总是有的。
这时,如何让数据在上下文中传递就是非常困难的,最简单的方式就是数据复制,把上下文中的数据都复制到新的上下文中,但是这时有个问题,有时候,你复制了许多数据,但是真正用到的数据很少,当然结果返回也是要一路复制回去的,这就导致了浪费,同时也消耗了时间和空间。
为此我们提出了上下文嵌套模式,通过上下文互相嵌套来避免数据复杂带来的性能影响,从此数据不再需要复制。
基本的上下文接口如下,可以看出,它和Map的接口是非常相似的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
|
接下来定义多层次上下文接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
|
可以看到,引入了父环境和子环境的概念,一个上下文只能有一个父环境,但是可以有多个子环境。通过环境嵌套,我们简单的解决了环境变量的复制问题。 上下文变量的读取,也很简单,采用递归算法,先从当前上下文读取,当前上下文中读不到的时候,就从子上下文读,子上下文读不到的时候,再从父上下文读。
于是我们构建了一个完美的死循环--这个是真的,实际上程序真的就陷入了死循环之中,接下来我们的注意力就集中在如何让死循环不死上,这个问题当然必须要解决,解决掉死循环之后,所有关系上下文之上的难题就都没有了,至此,我们拥有了高效的易用的上下文,下面看看测试用例:
1 2 3 4 5 6 7 8 9 10 11 |
|
可以看到,确实,只要把testContext放在context之间,它们就可以互相访问对方的变量。
上下文的重要性在Tiny框架中是毫无置疑的,它大大简化了程序结构,提升了访问效率,在许多的子工程中都引用了上下文,可以说,没有上下文的良好实现,就不会有后续的高效与易用。