现在的位置: 首页 > 综合 > 正文

围绕EMF探索(2)之再探查询组件

2013年11月26日 ⁄ 综合 ⁄ 共 2048字 ⁄ 字号 评论关闭

 

围绕EMF探索(2)之再探查询组件
 
       本篇专门讲讲EMF Query这个组件的设计原理、结构和算法
       在上一篇中,已经简单介绍了EMF Query,其是为“内存中的eObjects”的检索提供一套“查询条件”,可以依据eObject的结构关系进行查询,也可以依据eObject的对象进行查询。
 
       EMQ Query的主结构关系如下图所示:
       其中咖啡色表示最基本的设计思想的基类,把握住了这几个类(接口),则就把握了整个EMF Query的设计原理。
       其中蓝色的图形表示主要所需要关注的实现类和构架。
 
       从大的方面说,整个EMF Query是由围绕查询语句的构造和执行来展开的。
       (1)查询语句的结构
             
              查询语句的结构一般如下所示:
SELECT
       FROM [source]
       WHERE [condition]
              整个查询语句(SELECT)是由两个查询子句(Query Clause)组成,分别是FROM和WHERE。其中FROM表示了所需要查询的对象源(EObject Source),WHERE则表示了所需要匹配的条件。
              对于EObject Source,其表示的就是一组eObject对象的集合。
 
       (2)查询语句的执行
              整个查询语句的执行规则就是,将所需要检索的对象源(EObject Source)转换成一棵对象树,通过遍历这棵对象树,依次将树中的对象与所需要检索的条件进行匹配,选择匹配成功的
 
EObject eObject = null;
boolean canPrune = getFromClause().canBePruned();
WHERE whereClause = getWhereClause();
while (it.hasNext() && (isCancelled() == false)) {
       eObject = (EObject) it.next();
       if (whereClause.matches(eObject)) {
              addEObject(eObject);
              if (getResultSet().size() == maximumResultSize) {
                     break;
              }
       }
       if (canPrune && whereClause.shouldPrune(eObject)) {
              it.prune();
       }
 
}
 
       有关上面那张类图的结构就不再多叙述,相信一看就明白。
       接下来讲讲两个比较值得关注的地方,一个是看得见的条件(Condition),还有一个是看不见的Tree Prune。
 
条件(Condition)
       与条件相关的类几乎占据了整个Query组件的一半,但是这些Condition是非常简单的。如果想真正理解这个条件的构造机制和原理,那么建议大家花点时间了解一下Java Funtion Programming(Java的函数式编程)。整个Condition就是围绕一个“一元谓词”而构造的,而每个Condition实际上就代表一个算子(arithmetic operator)。
       其实上一篇已经提到了我曾经写过一篇有关Java函数式编程的blog,参见http://blog.csdn.net/james999/archive/2005/01/09/246404.aspx
 
       大家在使用或阅读Query源码的时候,可能会涉及到有的Condition会存在Adapter的。其实这就是利用了一个简单的Adapter模式代码,将需要匹配的EObject转换成当前Condition可以识别的值,用于计算。
 
对象树的裁减
       前面讲过在执行检索过程中,要检索的对象源(EObject Source)转换成一棵对象树。其实是获取一个新的EMF所提供的TreeIterator对象,这是一个允许被裁减(Prune)的针对树的遍历指针。
       TreeIterator的默认遍历方式是采用“树的深度遍历算法”,而裁减(Prune)则表示:当遍历到某个节点时,如果执行裁减行为,则此节点后的所有子节点将不再遍历——就像一棵树,被削了一个枝杈似的。
       因为EMF的对象是支持包含关系的,而且很容易通过getContents()接口获取相关的内容对象。虽然如果不进行适当的裁减操作,完整的遍历一棵树,是比较缓慢的。
       EMF Query在构造Condition的时候,提供了PruneHandler接口,用于判断当前的eObject对象是否需要进行裁减遍历行为。

抱歉!评论已关闭.