收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


javasscc的笔记
状态: 离线
人气:499807
访问用户量:1134
笔记经验:1858
总积分:1958
级别:普通会员
搜索本笔记
ta的交流分类
ta的交流主题贴(196)
ta的所有交流贴(200)
ta的全部笔记
全部笔记(98)
未分类笔记(0)
研磨设计模式(94)
课程问题(0)
设计模式综合项目实战(4)
存档
2013-05(4)
2012-08(39)
2012-07(55)

2012-08-20 14:16:45
研磨设计模式 之 解释器模式(Interpreter)1——跟着cc学设计系列
浏览(4609)|评论(0)   交流分类:Java|笔记分类: 研磨设计模式

21.1  场景问题

21.1.1  读取配置文件

       考虑这样一个实际的应用,维护系统自定义的配置文件。

几乎每个实际的应用系统都有与应用自身相关的配置文件,这个配置文件是由开发人员根据需要自定义的,系统运行时会根据配置的数据进行相应的功能处理。

       系统现有的配置数据很简单,主要是JDBC所需要的数据,还有默认读取Spring的配置文件,目前系统只需要一个Spring的配置文件。示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<root>

    <jdbc>

       <driver-class>驱动类名</driver-class>

       <url>连接数据库的URL</url>

       <user>连接数据库的用户名</user>

       <password>连接数据库的密码</password>

    </jdbc>

    <application-xml>缺省读取的Spring配置的文件名称</application-xml>

</root>

       现在的功能需求是:如何能够灵活的读取配置文件的内容?

21.1.2  不用模式的解决方案

       不就是读取配置文件吗?实现很简单,直接读取并解析xml就可以了。读取xml的应用包很多,这里都不用,直接采用最基础的Dom解析就可以了。另外,读取到xml中的值过后,后续如何处理,这里也不去管,这里只是实现把配置文件读取并解析出来。

       按照这个思路,很快就写出了实现的代码,示例代码如下:

/**

 * 读取配置文件

 */

public class ReadAppXml {

    /**

     * 读取配置文件内容

     * @param filePathName 配置文件的路径和文件名

     * @throws Exception

     */

    public void read(String filePathName)throws Exception{

       Document doc = null;

       //建立一个解析器工厂

       DocumentBuilderFactory factory =

DocumentBuilderFactory.newInstance();

        //获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器

       DocumentBuilder builder=factory.newDocumentBuilder();

       //得到一个表示XML文档的Document对象

       doc=builder.parse(filePathName);

       //去掉XML中作为格式化内容的空白而映射在DOM树中的Text Node对象

       doc.normalize();

      

       //获取jdbc的配置值

       NodeList jdbc = doc.getElementsByTagName("jdbc");

       //只有一个jdbc,获取jdbc中的驱动类的名称

       NodeList driverClassNode = ((Element)jdbc.item(0))

.getElementsByTagName("driver-class");

       String driverClass = driverClassNode.item(0)

.getFirstChild().getNodeValue();

       System.out.println("driverClass=="+driverClass);

       //同理获取url、user、password等的值

       NodeList urlNode = ((Element)jdbc.item(0))

.getElementsByTagName("url");

       String url=urlNode.item(0).getFirstChild().getNodeValue();

       System.out.println("url=="+url);

      

       NodeList userNode = ((Element)jdbc.item(0))

.getElementsByTagName("user");

       String user = userNode.item(0).getFirstChild()

.getNodeValue();

       System.out.println("user=="+user);

      

       NodeList passwordNode = ((Element)jdbc.item(0))

.getElementsByTagName("password");

       String password = passwordNode.item(0).getFirstChild()

.getNodeValue();

       System.out.println("password=="+password);

      

       //获取application-xml

       NodeList applicationXmlNode =

doc.getElementsByTagName("application-xml");

       String applicationXml = applicationXmlNode.item(0)

.getFirstChild().getNodeValue();

       System.out.println("applicationXml=="+applicationXml);

    }

}

21.1.3  有何问题

       看了上面的实现,多简单啊,就是最基本的Dom解析嘛,要是采用其它的开源工具包,比如dom4j、jDom之类的来处理,会更简单,这好像不值得一提呀,真的是这样吗?

请思考一个问题:如果配置文件的结构需要变动呢?仔细想想,就会感觉出问题来了。还是先看例子,然后再来总结这个问题。

随着开发的深入进行,越来越多可配置的数据被抽取出来,需要添加到配置文件中,比如与数据库的连接配置:就加入了是否需要、是否使用DataSource等配置。除了这些还加入了一些其它需要配置的数据,例如:系统管理员、日志记录方式、缓存线程的间隔时长、默认读取哪些Spring配置文件等等,示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<root>

    <database-connection>

       <connection-type>连接数据库的类型,1-用Spring集成的方式

(也就是不用下面两种方式了),2-DataSource(就是使用JNDI),

3-使用JDBC自己来连接数据库

       </connection-type>

       <jndi>DataSource的方式用,服务器数据源的JNDI名称</jndi>

       <jdbc>跟上面一样,省略了</jdbc>

    </database-connection>

    <system-operator>系统管理员ID</system-operator>

    <log>

       <operate-type>记录日志的方式,1-数据库,2-文件</operate-type>

       <file-name>记录日志的文件名称</file-name>

    </log>

    <thread-interval>缓存线程的间隔时长</thread-interval>

    <spring-default>

       <application-xmls>

           <application-xml>

缺省读取的Spring配置的文件名称

           </application-xml>

           <application-xml>

其它需要读取的Spring配置的文件名称

           </application-xml>

       </application-xmls>

    </spring-default>

</root>

有朋友可能会想,改变一下配置文件,值得大惊小怪吗?对于应用系统开发来讲,这不是经常发生的、很普通的一件事情嘛。

       的确是这样,改变一下配置文件不是件大事情,但是带来的一系列麻烦也不容忽视,比如:修改了配置文件的结构,那么读取配置文件的程序就需要做出相应的变更;用来封装配置文件数据的数据对象也需要相应的修改;外部使用配置文件的地方,获取数据的地方也会相应变动。

       当然在这一系列麻烦中,最让人痛苦的莫过于修改读取配置文件的程序了,有时候几乎是重写。比如在使用Dom读取第一个配置文件,读取默认的Spring配置文件的值的时候,可能的片断代码示例如下:

//获取application-xml

    NodeList applicationXmlNode =

doc.getElementsByTagName("application-xml");

    String applicationXml = applicationXmlNode.item(0)

.getFirstChild().getNodeValue();

    System.out.println("applicationXml=="+applicationXml);

但是如果配置文件改成第二个,文件的结构发生了改变,需要读取的配置文件变成了多个了,读取的程序也发生了改变,而且application-xml节点也不是直接从doc下获取了。几乎是完全重写了,此时可能的片断代码示例如下:

    //先要获取spring-default,然后获取application-xmls

    //然后才能获取application-xml    

    NodeList springDefaultNode =

doc.getElementsByTagName("spring-default");

    NodeList appXmlsNode = ((Element)springDefaultNode.item(0))

.getElementsByTagName("application-xmls");

    NodeList appXmlNode = ((Element)appXmlsNode.item(0))

.getElementsByTagName("application-xml");

    //循环获取每个application-xml元素的值

    for(int i=0;i<appXmlNode.getLength();i++){

       String applicationXml = appXmlNode.item(i)

.getFirstChild().getNodeValue();

       System.out.println("applicationXml=="+applicationXml);

    }

       仔细对比上面在xml变化前后读取值的代码,你会发现,由于xml结构的变化,导致读取xml文件内容的代码,基本上完全重写了。

问题还不仅仅限于读取元素的值,同样体现在读取属性上。可能有些朋友说可以换不同的xml解析方式来简化,不是还有Sax解析,实在不行换用其它开源的解决方案。

       确实通过使用不同的解析xml的方式是会让程序变得简单点,但是每次xml的结构发生变化过后,或多或少都是需要修改程序中解析xml部分的。

       有没有办法解决这个问题呢?也就是当xml的结构发生改变过后,能够很方便的获取相应元素、或者是属性的值,而不用再去修改解析xml的程序。

 


---------------------------------------------------------------------------

私塾在线学习网原创内容  跟着cc学设计系列 之 研磨设计模式

研磨设计讨论群【252780326】

原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/5665.html

---------------------------------------------------------------------------

相关笔记推荐
精品视频课程推荐

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

深入浅出学Spring Web MVC视频教程
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识

高级软件架构师实战培训阶段一
内容概述:本课程专注于构建:高可扩展性、高性能、大数据量、高并发、分布式的系统架构。 从零开始、全面系统、成体系的软件架构课程,循序渐进的讲述构建上述系统架构所需要的各种技术知识和技能。
技术要点: 1:构建基本的业务功能块,基于Maven+Git+Spring mvc+spring+mybatis+ehcache+mysql+X-gen代码生成
 2:高扩展性的分布式体系架构(基于Nginx+Varnish+Memcache+ActiveMQ)
 3:NoSQL的合理使用和架构优化(基于MongoDB)
 4:分布式文件存储和架构优化(基于MogileFS)

ssh+jbpm项目(某集团OA)视频教程
达到能综合使用Struts2+Spring3+Hibernate3+Jbpm4来进行实际项目开发的能力。 包括:ssh和jbpm的整合;数据字典;通用DAO(Spring+Hibernate+泛型+反射+SpEL+模板方法模式);自动生成UUID的加强版;分层开发、SSH联合的基本开发;翻页的taglib;示范真实值和表现值,数据参照的实现;文件上传下载;主子表操;登录验证码;登录控制的拦截器

《设计模式综合项目实战》——跟着cc学设计系列精品视频教程

浏览(4609)|评论(0)   交流分类:Java|笔记分类: 研磨设计模式

评论(0)
请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网