收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 

交流首页 » 软件设计专版 »x-gen代码生成器配置管理1——设计模式综合项目实战 x-gen代码生成器视频教程  XML
发表人 内容
javasscc
[头像]

交流经验:
总积分:1958
级别:普通会员
注册时间: 2011-10-24
文章: 200
离线

配置管理模块的详细功能

n获取用户配置的数据

  配置的方式很多,要求除了框架自身提供的配置方式外,还要能支持用户自定义的配置方式。比如:框架本身提供默认的配置方式为xml配置,如果用户想使用数据库来配置,那么框架必须能够支持用户自定义一种数据库配置的方式 ,并能够很容易的加入到系统中进行使用。

 

n缓存用户配置的数据

  同一份配置数据,在运行期间会多次使用,但是获取用户配置数据的动作就只需要一次就可以了,获取过后,就缓存下来,重复使用了。

 

n对外提供接口

  让其他模块通过这些接口来获取他们需要的数据

 

配置管理模块的功能边界

n配置管理模块的功能边界

1:配置管理模块不关心被访问的数据是怎么来的,它只是按照访问方式去获取这些数据,当然不同的数据格式有不同的访问方式。

2:虽然需要支持自定义配置方式,但是需要配置的数据是一定的,只是配置的格式不同,访问这些配置数据的方式不同,但最后殊途同归,都想配置管理模块提供相应的数据。因此这个需要配置的数据项是要统一起来的。

3:配置管理模块不关心获取到的数据是什么,也不关心这些数据的含义,更不关心这些数据怎么用,它只是负责获取这些数据并保存起来。

4:配置管理模块不关心谁来使用这些数据,也不关心外部获取这些数据后如何使用,它只是负责提供这些数据而已。

 

配置管理模块的对外接口

n对外数据接口设计

  目前设计的配置分成三类,虽然配置的方式不固定,但是对于核心框架而言,有一些数据是必需要配置的,所以还是需要设计对外的数据接口。

  为了简单,这里以xml为例子来说明定义的数据结构。但是请注意,x-gen框架并不局限于使用xml作为配置的方式,同样你可以选用properties文件、数据库等其他的配置方式。

  虽然配置方式不同,需要配置的数据却是一样的,所以,你可以把这里xml描述的配置数据改成任何你希望使用的配置方式相对应的数据结构。

 

n第一类是核心框架运行需要的数据

  以xml配置为例,默认取名为GenConf.xml,在每次使用的时候根据需要修改或配置其内容。当然,为了示例简单,就不去做dtd或者schema了。 

 

 

java代码:
<?xml version="1.0" encoding="UTF-8"?>
<GenConf>
	<NeedGens>
		<NeedGen id="UserGenConf" provider="XmlModuleGenConf" themeId="simple">
			<Params>
				<Param id="fileName">UserGenConf.xml</Param>
			</Params>	
		</NeedGen>
	</NeedGens>
	<Themes>
		<Theme id="simple">cn/javass/themes/simple</Theme>
	</Themes>
  <Constants>
		<Constant id="prePackage" value="cn.javass"></Constant>
		<Constant id="projectName" value="framework"></Constant>
	</Constants>
</GenConf>

 

n节点说明如下:

(1)<GenConf>是根节点

(2)<NeedGens> :用来注册需要generate的模块的配置,里面可以注册很多个需要generate的模块

(3)<NeedGen> :需要generate的一个模块,属性含义如下:

  Id:需要generate的模块的标识名称或编号,必须唯一

  provider:用来获取该模块配置数据的程序的标识,该标识对应的实现类定义,在该模块使用的theme里面配置

  themeId:该模块生成的时候具体使用的theme的标识

(4)<Params>:参数,通常是根据不同的provider,提供不同的参数配置,每个参数配置都包括参数标识和具体的参数值

(5)<Param>:具体一个参数的配置,值就是参数的值,属性如下:

  Id:参数的标识名称或编号,必须唯一

(6)<Themes>:用来注册generate所需要的外部theme,可以配置多个<Theme>

(7)<Theme>:具体的描述一个theme,theme存放的具体位置,可以配置一个相对路径,配置到theme存放的根文件夹即可,属性如下:

  Id:theme的标识名称或编号,必须唯一

(8)<Constants>:常量定义,可以配置多个常量

(9)<Constant>:单个常量定义,值就是常量的值,属性为:

  id :常量的标识名称或编号,必须唯一

 

n第二类是用户需要生成的模块的配置数据

  比如:用户想要生成一个模块内的增删改查的源代码,里面有每个具体功能的配置,而每个具体功能就是一个源代码文件。

  这个也需要在每次使用的时候根据需要来配置,并注册到核心框架运行配置里面去,每次生成主要配置的就是这类数据。示例如下:

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

<ModuleGenConf id=“UserConf”>

  <NeedGenTypes>

  <NeedGenType id="GenBusinessEbi">

  <NeedGenOutType id="File"></NeedGenOutType>

  </NeedGenType>

  </NeedGenTypes>

  <ExtendConfs>

  <ExtendConf id="moduleName" isSingle="true">user</ExtendConf>

  </ExtendConfs>

</ModuleGenConf> 

 

n节点说明如下:

(1)<ModuleGenConf>:每个模块配置的根节点,属性如下:

  id:模块的标识,不重复即可

(2)<NeedGenTypes>:用来配置需要生成的功能,可以配置多个

(3)<NeedGenType>:配置一个本模块需要生成的功能,属性如下:

  id:需要生成的功能的标识,这个标识在theme的配置中定义

(4)<NeedGenOutType>:配置模块的某个功能生成完成后,输出的类型,一个功能可以有多种输出。属性如下:

  id:具体输出的标识,这个标识在theme的配置中定义

(5)<ExtendsConfs>:本模块需要配置的,自行扩展的数据,可以配置多个数据。

(6)<ExtendConf>:描述一条自行扩展的数据,属性如下:

  id:自定义数据的标识

  isSingle:数据是单个值还是一个数组,true表示是单个值,false表示是数组,如果是数组的话,多个值之间用逗号分开

 

n第三类就是外部主题的配置数据

  在制作主题的时候就配置好,里面有这套主题需要的外部数据,和预定义好的功能配置,在每次使用的时候一般不需要配置或修改。比如:缺省为xml配置,取名为ThemeConf.xml。

  外部主题目前不支持自定义,也就是采用默认的xml方式,而且文件名称也固定是ThemeConf.xml,其实要实现支持自定义也很简单,只是没有必要,那样会无谓的增加复杂度。

  示例如下:

 

java代码:
<?xml version="1.0" encoding="UTF-8"?>
<Theme id="simple">
  <GenTypes>
    <GenType id="GenBusinessEbi" type="cn.javass.themes.simple.actions.GenBusinessEbiAction">
      <Params>
        <Param id="relativePath">business.ebi</Param>
        <Param id="mbPathFile">business/Ebi.txt</Param>
        <Param id="preGenFileName"></Param>
        <Param id="afterGenFileName">Ebi.java</Param>
      </Params>
    </GenType>
  </GenTypes>
  <GenOutTypes>
    <GenOutType id="Console" type="cn.javass.xgen.output.types.OutputToConsole"></GenOutType>
    <GenOutType id="File" type="cn.javass.xgen.output.types.OutputToFile"></GenOutType>
  </GenOutTypes>
  <Providers>
    <Provider id="XmlModuleGenConf" type="cn.javass.xgen.genconf.implementors.xmlimpl.ModuleGenConfXmlImpl"></Provider>
  </Providers>  
</Theme>

 

(1)<Theme>:主题配置的根节点,属性如下:

  id:主题的标识,必须唯一,在GenConf注册theme的id就是这个值

(2)<GenTypes>:主题提供的可输出的功能,可配置多个

(3)<GenType>:描述一个主题可输出的具体功能,属性如下:

  id:功能的标识,必须唯一,在ModuleGenConf里面配置每个模块的NeedGenType的id就是这个值

  type:真正实现输出功能的类

(4)Params:配置每个输出类需要的参数,下面可以配置多个param

(5)param:具体的每个参数的配置,值就是参数的值,属性为:

  id:参数的标识,在一个params必须唯一

(6)GenOutTypes:主题提供的输出类型,可以配置多个

(7)GenOutType:一个具体的输出类型,属性如下:

  id:功能的标识,必须唯一,在ModuleGenConf里面配置每个模块的NeedGenOutType的id就是这个值

  type:真正实现输出类型的类

(6)Providers:主题提供的读取配置文件的类型,可以配置多个

(9)Provider:一个具体的读取配置文件的类型,属性如下:

  id:功能的标识,必须唯一,在GenConf里面配置NeedGen的provider就是这个值

  type:真正实现具体的读取配置文件的类

 

n对外程序接口设计

  为了让外部获取配置管理模块内的数据,提供相应的API(应用程序接口),也就是GenConfEbi

 

配置管理模块的内部实现

 

n实现的起点

 

  为了让大家更好的理解配置管理模块的内部实现架构,因此先以一个最简单的实现结构为起点,采用重构的方式,逐步把相关的设计模式应用进来,从简单到复杂,从而让大家更好的看到如何选择要使用的设计模式、如何实际应用设计模式以及如何让多种设计模式协同工作。

 

  1:先就来看看实现配置管理的起点,首先根据对外提供的数据结构定义,制作出相应的数据model来。

 

  2:针对前面定义的API,提供一个最基本的实现,只需要满足最基本的功能就可以了,需要实现读取配置文件的功能,然后要有缓存配置数据的功能,最后就是实现API中要求的功能。

 

n此时配置管理模块的结构示意如图

加入简单工厂

n面临的问题 

  观察上面的实现,向模块外部提供了接口,可是外部根本不知道模块内部的具体实现,那么模块外部如何来获取一个实现接口的实现对象呢?

n用简单工厂来解决

  简单工厂是解决上述问题的一个合理方案。那么先一起来回顾一下简单工厂的一些基础知识,然后再来看如何应用它来解决上面的问题。

n简单工厂基础回顾 
初识简单工厂
n定义

  提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。

n结构和说明

  Api:定义客户所需要的功能接口

  Impl:具体实现Api的实现类,可能会有多个

  Factory:工厂,选择合适的实现类来创建Api接口对象

  Client:客户端,通过Factory去获取Api接口对象,然后面向Api接口编程  

简单工厂的知识要点

n简单工厂的知识要点  

1:简单工厂位于对外提供接口的模块内

2:简单工作的主要功能就是用来创建对象实例,被创建的对象可以是接口、抽象类或是普通的类

3:简单工厂可以实现成为单例,也可以实现成静态工厂

4:简单工厂的内部实现,主要是做“选择合适的实现”,实现是已经做好的,简单工厂只是来选择使用即可

5:简单工厂在进行选择的时候,需要的参数可以从客户端传入、配置文件、或者是运行期程序某个运行结果等

6:如果使用反射+配置文件的方式,可以写出通用的简单工厂

 

思考简单工厂

n简单工厂的本质  

  简单工厂的本质是:选择实现

 

n何时选用简单工厂  

1:如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现

 

2:如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制

 

应用简单工厂

n 使用简单工厂来解决问题的思路  

  简单工厂解决这个问题的思路就是,在配置管理模块里面添加一个类,在这个类里面实现一个方法,让这个方法来创建一个接口对象并返回然后把这个类提供给客户端,让客户端通过调用这个类的方法来获取接口对象。

n此时配置管理模块的结构示意如图 
加入单例模式
n面临的问题 

  看看上面的基本实现,会发现一些问题:

1:如果GenConfEbo被创建多次的话,那么就会重复获取配置数据,浪费程序运行时间;

2:并且每个GenConfEbo的实例都会缓存这些数据,浪费内存空间。

3:同一个类里面,既有实现GenConfEbi要求的对外功能,又有内部实现需要的获取配置数据和缓存数据的功能,从类的设计上来说,这个类的职责太不单一了,应该分离一部分职责出去。

  因此这种实现肯定是不好的,那么怎么解决呢?

n用单例模式来解决

 

n单例模式基础回顾 

初识单例模式

n定义

  保证一个类仅有一个实例,并提供一个访问它的全局访问点。

n结构和说明

Singleton:

  负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,让外部来访问这个类的唯一实例。

 

单例模式的知识要点

n单例模式的知识要点  

1:单例模式是用来保证一个类在运行期间只会被创建一个类实例的

2:单例模式还提供了一个全局唯一访问这个类实例的访问点,通常就是那个getInstance方法

3:单例模式只关心类实例的创建问题,并不关心具体的业务功能。

4:单例模式是一个虚拟机范围内单例,不适用于集群等环境

5:单例模式的实现有很多种,除了常见的懒汉式和饿汉式外,还有利用缓存来实现、双重检查加锁的实现、Lazy initialization holder class模式、以及枚举的实现方式等

6:使用单例模式的时候要注意它的线程安全性

7:单例模式体现了延迟加载、缓存等常见的设计思想

8:单例模式是可以很容易的扩展到多实例控制的

 

思考单例模式

n单例模式的本质  

  单例模式的本质是:控制实例数目

n
n何时选用单例模式 

  当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式,这些功能恰好是单例模式要解决的问题

 

应用单例模式

n此时配置管理模块的结构示意如图 

 

私塾在线原创精品课程,转载请注明私塾在线【http://sishuok.com/forum/blogPost/list/0/6789.html


推广链接
精品视频课程推荐

透彻理解JavaBean视频教程
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

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

Ajax+JSON基础实战视频教程
数据校验、Javascript模拟多线程、下拉列表联动、操作XML、AJAX结合JSON的操作、Json-lib的使用

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

 
交流首页 » 软件设计专版
Message 快速回复

前往:   

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

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