《测试驱动开发与设计模式》开发实例二 JSON过滤库

0.1 版权声明

测试驱动开发与设计模式相结合的开发方式,能产生清晰的结构,弹性的设计,水到渠成地还带来稳定的代码。这里对JSON过滤库的介绍,是为了说明这种方式的好处,也是对《测试驱动开发与设计模式 - 从入门到精通》一文的补充。

JSON过滤库作为A公司项目的一部分完成,版权属于A公司。

0.2 设计目的

这个库的目的是用 “Json字符串” 匹配 “Json过滤字符串”,如果匹配,则认为过滤成功,否则失败。

Json字符串是符合Json规范的字符串,Json过滤字符串则是符合MongoDB查询操作规范的字符串。

比如Json字符串如下:

{
    "name":"ron",
    "sex":"male",
    "position": 
    {
        "x":100,
        "y":200
    }
}

如果过滤字符串如下,则是成功的,因为sex属性和position.x属性是匹配的。

{"sex":{"$eq","male"},"position":{"x":{"$lte":100}}

如果过滤如下,则是失败的,因为name属性不匹配。

{"name":{"$eq":"josh"}}

1. Constraint

  • Constraint是条件约束。CommonConstraint是一般条件,CompositeConstraint是组合条件,也就是其他条件的组合,这个其他条件可以是一般条件,也可以是组合条件。
  • CommonConstraint包括EqContraint,LteConstraint,RegexConstraint等,分别对应MongoDB的$eq,$lte, $regex;
  • CustomedConstraint也是CommonConstraint,它是用户自定义的类型;
  • CompositeConstraint包括AndConstraint,OrConstraint,和NotConstraint等,分别对应MongoDB的$and, $or, $not。

2. ConstraintTree和Node

  • Json字符串实际上是一棵树,而“Json过滤字符串”则是两棵树,一棵是属性树,另一棵是条件树,后者按照Constraint的位置挂接在前一棵上。这里用ConstraintTree表示“Json过滤字符串”的树(它的数据表示是ConstraintTreeData),而Node就是树节点;
  • Attribute是属性树的节点,ConstraintTreeData用root属性引用属性树;
  • Constraint是条件树的节点,所有的条件最后组合成为一个AndConstraint,保存在ConstraintTreeData的subs成员中;
  • 实际上这里支持多组条件的,也就是有多个条件树,所以ConstraintTreeData.subs是一个map。既然有多组条件,就需要对它们编号,所以从AndConstraint派生出Subscriber,保存这个编号。

3. 构建ConstraintTree

  • 将“Json过滤字符串”传给ContraitTree进行构建。ContraintTree将ContraintTreeData给Builder,委托它完成工作。
  • JsonNode表示Json字符串。因为效率的原因,它其实是一种Binary JsonNode,来自于另一个库。
  • Builder解析"Json过滤字符串”,并相应地构建属性树和条件树;
  • 可以多次构建,得到多个条件树,对应于多个Subsriber。

3. 过滤

  • Visitor提供一个方便遍历ConstraintTreeData节点的接口;
  • Visitor还包含VistorData,保存过滤的状态和结果。VisitorData是每线程构建的,所以可以用同一个ContraintTree实例并行做多个过滤。
  • Traverser同时遍历ContraintTreeData的树(通过Visitor),和传入的Json字符串,剔除不满足的Subscriber,留下满足条件的。这实际上是反向过滤。
  • 当然,如果Subscriber只有一个,而且被剔除了,那就说明Json字符串不符合条件,反向过滤也就是正向过滤了。

4. 对外的接口

  • Filter和FilterFactory是对外的接口。FilterImp基于ContraintTree实现Filter接口。

5. 构造Json过滤字符串

  • 如果对Json和MongoDB查询不熟悉,那么写Json过滤字符串算是一个不大不小的麻烦事。Cons和它的派生类帮助使用者用一种容易理解的方式来写。
  • EqCons,GtCons, RegexCons等分别用来构造$eq, $gt和$regex字符串。
  • Cons本身还有函数支持写组合条件,如operator &&,operator || 和 operator !分别用于$and, $or, $not等。

6. 多个Json过滤字符串

  • 与Filter/FilterFactory一样,PhasedFilter/FilterFactory也是对外的接口。不过,PhasedFilter支持多步骤的过滤。也就是Json字符串可以分几次输入。

相关链接

测试驱动开发与设计模式 - 为什么使用测试驱动开发
测试驱动开发与设计模式 - 从入门到精通
测试驱动开发与设计模式 - C++书籍及网站
测试驱动开发与设计模式 - 适应并改进软件设计过程
测试驱动开发与设计模式 - 让“理想结构”与“快速变更”并行
测试驱动开发与设计模式 - 提速 — 在纸上做细节设计
测试驱动开发与设计模式 - 开发实例一 DVR-POS库
测试驱动开发与设计模式 - 开发实例二 JSON过滤库
测试驱动开发与设计模式 - 开发实例三 DVR-POS库

你可能感兴趣的:(《测试驱动开发与设计模式》开发实例二 JSON过滤库)