Digester:一个通用xml引擎的设计剖析

简介:

   一:Digester介绍

   Digester是Jakarta 子项目Commons下的一个模块,支持基于规则的对任意XML文档的处理。它最初是Structs项目的

一部分,后因其通用性而划归Commons.

   本文不是描述Digester如何使用,而是深入分析Digester的源码,对其设计进行分析,从而从中学到设计方法和一些设计

理念,正所谓“授人鱼,不如授人以渔”。

 

   二:不好的设计

  Digester要解决的问题看起来很简单:根据xml文件定义,来生成指定的对象。估计大部分人的第一反应就是if-else,由于

xml类似是树形结构的,因此为了完成一个xml文件的解析,需要if-else加上递归才能完成一个xml文件的解析,例如下面的

xml文件,于下面的写法:

                                                if( element = "book")

                                                {

                                                      processBook();

                                                 }

 

                                                if( element = "name ")

                                                {

                                                      processName();

                                                 }

                                                 .....................................

 

    从功能上来说,这样也确实是能够实现功能,但从设计角度来说,这样几乎是没有任何设计,为什么呢?

    这样的设计存在的主要问题如下:

    1)代码和xml结构和元素绑定,一旦xml结构变化,或者element的处理变化,解析代码就需要跟着调整;

    2)由于上面问题,导致这个所谓的xml引擎无法被重用,每个不同的项目采用不同的xml文件,都需要重新编写代码。

    总结来说,这个设计就是没有任何封装,无法重用,不能适应任何变化。

 

   三:Digester设计分析

    下面我们看看Digester是如何设计的。

    通过上面的一个样例分析,我们知道设计一个通用xml引擎要面临的设计问题有:

1xml文档格式不定;(2)每个xml对象的处理方式是可以变化的。

  那么,Digester是如何解决这两个问题呢?

 

  我们首先来看Digester的运行机制,如下是Digester的类结构图:

  

     Digester

 

 

1)  首先,Client需要创建一个Digester对象;

2)  然后,Client必须根据自己的xml格式来添加所有的Rule

3)  添加完Rule后,Client调用Digesterparse操作来解析xml文件。

4)  Digester实现了SAX的接口,解析时遇到具体的xml对象时会调用starElement等接口函数

5)  在这些SAX接口函数中,会扫描规则链rules(图中的RulesBase对象),找到匹配规则,规则匹配一般都是根据具体的元素名称来进行匹配。

6)  找到对应的rule后,依次执行rule。这里starElement对应的是begin操作,endElement对应的是end操作。具体要

    做的事情都在每个rule的begin、body、end函数中。

7)  文档结束后,会执行所有rulefinish函数。

 

从以上的运行过程可以看出,Digester为了解决面临的两个问题,采用了巧妙的设计方法:

(1)xml格式变化:Digester把这个变化抛给具体用户去解决,用户在使用Digester之前必须自己根据自己的

xml文件格式来构造规则链,Digester只提供构造规则链的手段,体现了有所为有所不为的设计思想。

2)“处理方式变化”的问题,Digester将“处理方式”抽象为“规则rule”,一个规则对应一个处理方式。

Digester提供了通用的缺省的Rule,如果用户觉得Digester提供的规则不满足自己的要求,可以自己另外定制,样例

dbinsert就体现了这种情况。

 

有了以上的设计,Digester完全就是一个通用的xml引擎了,只要你根据自己的应用写对应的Rule就OK了,

个人想到的应用有(以下仅为推测,没有真正考核过是否是这样实现):

1)根据xml文件创建对象:例如struts,Android中由xml定义view;

2)根据xml文件执行操作:例如Ant,数据库操作;

3)根据xml文件定义流程:例如数据流、业务流处理;

........................(其它请大家自己发散了:-P)

 

四:Digester设计总结

    大部分人可能都知道设计模式中两个重要的设计原则“基于接口编程”和“封装变化”,但实际应用中如

体现呢?Digester为我们提供了很好的样例。

(1)基于接口编程:Digester的框架类都是接口或者虚类,例如Rules、Rule;

(2)封装变化:将具体的处理抽象为Rule,将xml的结构由用户去构造(因为这个无法抽象)。

顺便翻了一下《设计模式》,觉得Digester这种设计方法对应设计模式中的“策略模式”。

 

附:Digester源码CSDN上就有。

 

  

 

相关文章
|
XML Java 数据库连接
* 完成单表操作:需要3个功能。 * 功能1:使用注解 * 功能2:通用Mapper * 功能3:使用xml
* 完成单表操作:需要3个功能。 * 功能1:使用注解 * 功能2:通用Mapper * 功能3:使用xml
150 0
|
XML Java 数据格式
利用Digester把XML转换为Java对象
在一个比较完整的应用系统里,经常需要有一些配置文件。简单的属性使用.properties文件即可,但要配置一些复杂对象,则应该考虑使用xml文件。一般用来读取xml文件的工具包有DOM、SAX和JDOM等,但用过的人都知道,它们属于比较底层的API,写起来代码量很大,而且如果修改了xml文件的格式,代码也要做大幅度的改动。
1513 0
|
XML 数据格式
|
4月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
11月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
221 1
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
10月前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
796 8