强悍的上下文Context

在一个框架中,许多地方都要用到上下文(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

public interface BaseContext {

    /**

     * 添加到环境

     *

     * @param name

     * @param object

     */

    <T> T put(String name, T object);

 

    /**

     * 把环境中某键值的名字换成另外的名字

     * @param key

     * @param newKey

     * @return

     */

    boolean renameKey(String key, String newKey);

 

    /**

     * 遍历所有删除及子环境并删除找到的第一个

     *

     * @param name

     * @return

     */

    <T> T remove(String name);

 

    /**

     * 获取对象,如果当前环境中没有,则到子环境当中寻找

     *

     * @param name

     * @return

     */

    <T> T get(String name);

 

    /**

     *

     * @param name

     * @param defaultValue

     *            默认值

     * @return

     * @throws NotExistException

     */

    <T> T get(String name, T defaultValue);

 

    int size();

 

    /**

     * 检测变量是否存在

     *

     * @param name

     * @return 返回是否存在

     */

    boolean exist(String name);

 

    /**

     * 删除环境中的所有内容

     */

    void clear();

 

    /**

     * 返回环境中所有内容

     *

     * @return

     */

    Map<String, Object> getItemMap();

}

接下来定义多层次上下文接口:

?


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

/**

 * 多层环境

 *

 * @author luoguo

 *

 */

public interface Context extends BaseContext {

    /**

     * 创建子上下文

     *

     * @param contextName

     * @return

     */

    Context createSubContext(String contextName);

 

 

    /**

     * 从子环境删除

     * @param contextName 子环境

     * @param name 上下文变量名称

     */

    <T> T remove(String contextName, String name);

 

    /**

     * 从指定子环境获取变量

     *

     * @param contextName 子环境

     * @param name 上下文变量名称

     * @return @

     */

    <T> T get(String contextName, String name);

 

    /**

     * 添加到子环境

     *

     * @param contextName 子环境

     * @param name 上下文变量名称

     * @param object 要放入的数据

     *           

     */

    <T> T put(String contextName, String name, T object);

 

    /**

     * 返回父亲

     *

     * @return

     */

    Context getParent();

 

    /**

     * 设置父亲

     *

     * @param parent

     */

    void setParent(Context parent);

 

    /**

     * 添加子环境

     *

     * @param contextName 子环境

     * @param context

     * @return

     */

    Context putSubContext(String contextName, Context context);

 

    /**

     * 删除子上下文

     *

     * @param contextName 子环境

     */

    Context removeSubContext(String contextName);

 

    /**

     * 返回子环境

     *

     * @param contextName 子环境

     * @return 子环境

     */

    Context getSubContext(String contextName);

 

    /**

     * 删除所有子上下文

     */

    void clearSubContext();

 

    /**

     * 返回子环境MAP

     *

     * @return 子环境MAP

     */

    Map<<span></span>String, Context> getSubContextMap();

 

}

可以看到,引入了父环境和子环境的概念,一个上下文只能有一个父环境,但是可以有多个子环境。通过环境嵌套,我们简单的解决了环境变量的复制问题。 上下文变量的读取,也很简单,采用递归算法,先从当前上下文读取,当前上下文中读不到的时候,就从子上下文读,子上下文读不到的时候,再从父上下文读。

于是我们构建了一个完美的死循环--这个是真的,实际上程序真的就陷入了死循环之中,接下来我们的注意力就集中在如何让死循环不死上,这个问题当然必须要解决,解决掉死循环之后,所有关系上下文之上的难题就都没有了,至此,我们拥有了高效的易用的上下文,下面看看测试用例:

?


1

2

3

4

5

6

7

8

9

10

11

public void testGetSubContextMap() {

 Context context = new ContextImpl();

 context.put("name1", "value1");

 Context testContext = new ContextImpl();

 testContext.put("name3", "value3");

 context.putSubContext("test", testContext);

 String value3=context.get("name3");

 assertEquals("value3", value3);

 String value1=testContext.get("name1");

 assertEquals("value1", value1);

}

可以看到,确实,只要把testContext放在context之间,它们就可以互相访问对方的变量。 

上下文的重要性在Tiny框架中是毫无置疑的,它大大简化了程序结构,提升了访问效率,在许多的子工程中都引用了上下文,可以说,没有上下文的良好实现,就不会有后续的高效与易用。

时间: 2024-07-28 21:21:26

强悍的上下文Context的相关文章

Javascript的“上下文”(context)

一:JavaScript中的"上下文"指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. 在对象的激活过程中创建上下文,对象被配置为要求某些自动服务,如同步.事务.实时激活.安全性等等.又比如计算机技术中,相对于进程而言,上下文就是进程执行时的环境. 具体来说就是各个变量和数据,包括所有的寄存器变量.进程打开的文件.内存信息等.   JavaScript的执行上下文的理解是一

笔记 - Android - 6.上下文Context API

Context API:          File getFileDir():返回/data/data/应用程序包名/files 目录(应用程序的files目录)     File getCacheDir():返回/data/data/应用程序包名/cache 目录(应用缓存目录)          ------------          FileOutputStream openFileOutput(String name, int mode):创建一个输出流对象         > n

使用TinySpider实战抓取自己博客中的内容

因为做官网,没有内容,因此就想办法从OSChina中写的博客里弄点内容,这就要用到爬虫了. 然后就花了几分钟搞了一下,步骤如下: 第一步,写个方法抓目录: ? 1 2 3 4 5 6 7 8 9 10 11 public static void processCategory(String categoryId) {         Watcher watcher = new WatcherImpl();         Spider spider = new SpiderImpl();    

Javascript 中的上下文,我的认识的三个阶段

js 中的 上下文 Context,可以说是一个,你即使不知道,没听过,也不影响你继续写 js 代码的一个概念.但是,它又确确实实是无所不在的一个东西,是的,无所不在. 从我自己的经验来看,对上下文的认识,算是分成了三个阶段,每一个阶段,都让我从外在的表现中,理解了一些更本质上的东西. 第一阶段,不知 我最开始接触 js 的时候,看到了它的 new ,看到了它的 this ,很自然地会把 js 和其它的一些 OOP 语言等同起来看待,并且,好像,也是这么回事.比如: var Class = fu

用户空间与内核空间,进程上下文与中断上下文[总结]

1.前言 最近在学习linux内核方面的知识,经常会看到用户空间与内核空间及进程上下文与中断上下文.看着很熟悉,半天又说不出到底是怎么回事,有什么区别.看书过程经常被感觉欺骗,似懂非懂的感觉,很是不爽,今天好好结合书和网上的资料总结一下,加深理解. 2.用户空间与内核空间 我们知道现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操心系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保

基于 TensorFlow 的上下文机器人

本文讲的是基于 TensorFlow 的上下文机器人, 原文地址:Contextual Chatbots with Tensorflow 原文作者:gk_ 译文出自:掘金翻译计划 本文永久链接:https://github.com/xitu/gold-miner/blob/master/TODO/contextual-chat-bots-with-tensorflow.md 译者:edvardhua 校对者:lileizhenshuai, jasonxia23 基于 TensorFlow 的上下

final-Andoid如何获取string字符串,在一个类中没有context

问题描述 Andoid如何获取string字符串,在一个类中没有context 我们都知道,Android中在一个Activity或是service中可以用this.getString(R.string,test);来获取字符串,但如果这样呢? publicclass myTestClass{ public static final String MYTEST = "this is a test"; //如果这个字符串是在string.xml中,该如何获取该值 //this.getSt

jQuery技术内幕:深入解析jQuery架构设计与实现原理. 3.4 Sizzle( selector, context, results, seed )

3.4 Sizzle( selector, context, results, seed ) 函数Sizzle( selector, context, results, seed )用于查找与选择器表达式selector匹配的元素集合.该函数是选择器引擎的入口. 函数Sizzle( selector, context, results, seed )执行的6个关键步骤如下: 1)解析块表达式和块间关系符. 2)如果存在位置伪类,则从左向右查找: a.?查找第一个块表达式匹配的元素集合,得到第一个

Linux Context , Interrupts 和 Context Switching 说明【转】

转自:http://blog.csdn.net/tianlesoftware/article/details/6461207 一. 进程Context 定义        当一个进程在执行时, CPU的所有寄存器中的值.进程的状态以及堆栈中的内容,比如各个变量和数据,包括所有的寄存器变量.进程打开的文件.内存信息等.这些信息被称为该进程的上下文(Context).          一个进程的Context可以分为三个部分:用户级上下文.寄存器上下文以及系统级上下文:        (1)用户级