分类: C/C++
2008-04-03 17:33:03
模式的概念在软件行业被采用以后,得到的广泛的发展,现在已经存在许多种类型的模式应用,其中比较有名的箸作有:GoF(Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四人,简称:Gang of Four[GoF])的<设计模式,1995>,Martin Fowler的<分析模式,1997>,Frank Buschmann等人的<体系结构模式,1996、2000>、Jim O.Coplien、Niel Harrison等人的<编程模式,1995、1996、1998、1999>和Deepak Alur等人的 由于J2EE模式众多,篇幅有限,这里只概要介绍其中的一种应用模式 - 集成层的数据访问对象(DAO)模式,有兴趣的读者可以参看下面参考文献中的资料。 联系方式:
举一个模式应用的简单示例。例如,在你的便携式电脑上运行一个进程中的对象,并且这些对象需要和运行在另一进程中的别的对象通信,也许这一进程并不在你的便携式电脑上,而在别的地方。你又不想让系统中的对象担心如何找寻网上的其他对象或者执行远程过程调用。这时,可以使用代理(Proxy模式,详见GoF的<设计模式>一书)模式来解决这个问题,你能做的事就是为这个远程对象在你的本地过程中建立一个代理对象,该代理对象和远程对象具有相同的接口。你的本地对象利用通常处理过程中的消息发送来和代理交谈。这时代理对象负责把消息传送给实在对象,而不管实在对象位于何处。
由于下面要讲的Java 2平台的企业版(J2EE)应用模式中很多用到了设计模式与重构(Refactoring)的概念,所以在此有必要再概要介绍一下重构的概念。重构已经被证明可以阻止软件的腐朽和衰败,关于重构方面的有名箸作当然首推是Martin Fowler所写的<重构,1999>一书了,书中详细介绍了重构的七大类型,共70余种具体的重构手法,同时也指出测试机制在重构中的重要性。书中Martin Fowler对重构的概念进行了详细说明:
重构是对软件内部结构的一种调整,目地是在不改变[软件之可察行为]的前提下,提高其可理解性,降低其修改成本。重构是一种有纪律的、经过训练的、有条不紊的程序整理方法,可以将整理过程中不小心引入的错误的机率降到最低,本质上说,重构就是在代码写好之后改进它的设计。重构之前,首先检查自己是否有一套可靠的测试机制,这些测试必须有我检验能力。
建立于Java编程语言和Java技术基础之上的J2EE平台是最适用于企业级分布式环境的应用结构,它被设计为面向多层体系的结构。J2EE包含下面关键技术:Java服务器页面(Java Service Page,JSP)、Servlet、Enterprise JavaBeans(EJB)组件、Java消息服务(Java Message Service,JMS)、JDBC和Java命名与目录接口(Java Naming and Directory Interface,JNDI)。由于J2EE平台是分层系统,所以我们将J2EE的层次模型化,这个模型使得我们将职责逻辑地分到不同的层中,共分了五个层次:客户层、表示层、业务层、集成层和资源层。因为客户层和资源层并不是J2EE平台直接关注的问题,所以后面介绍的15个J2EE应用模式全部属于上面五层中的中间三层,其中表示层模式包含与Servlet和JSP技术相关的模式、业务层模式包含与EJB技术有关的模式、集成层模式包含与JMS和JDBC有关的模式。具体模式可参看下面表格:
表一:表示层模式
模式名
简单描述
截取过滤器(Intercepting Filter)
促进请求的预先处理和后处理
前端控制器(Front Controller)
提供请求处理的集中控制器
视图助手(View Helper)
把与表示层格式化无关的逻辑封装到助手组件
复合视图(Composite View)
从原子的子组件创建一个聚集视图
工作者服务(Service To Worker)
合并分发者组件、前端控制器和视图助手模式
分发者视图(Dispatcher View)
合并分发者组件、前端控制器和视图助手模式,把许多动作推迟到视图处理
表二:业务层模式
模式名
简单描述
业务委托(Business Delegate)
把表示层和服务层分隔开,并且提供服务的外观和代理接口
值对象(Value Object)
通过减少网络对话,以加速层之间的数据交换
会话外观(Session Facade)
隐藏业务对象复性,集中化工作流处理
复合实体(Composite Entity)
通过把参数相关的对象分组进单个实体bean,表示设计粗粒度实体bean的最好经验
值对象组装器(Value Object Assembler)
把来自多个数据源的值对象组装成一个复合值对象
值列表处理器(Value List Handler)
管理查询执行、结果缓冲、以及结果处理
服务定位器(Service Locator)
封装业务服务查找和创建的复杂性,定位业务服务工厂
表三:集成层模式
模式名
简单描述
数据访问对象(Data Access Object)
抽象数据源,提供对数据的透明访问
服务激发器(Service Activator)
加速EJB组件的异步处理
数据访问对象模式
数据访问对象模式
1、问题
根据数据源不同,数据访问也不同。根据存储的类型(关系数据库、面向对象数据库等)和供应商不同,持久性存储(比如数据库)的访问差别也很大。当业务组件(如会话bean)或表示组件(如助手组件)需要访问某数据源时,它们可以使用合适的API来获得连接性,以及操作该数据源。但是在这些组件中包含连接性和数据访问代码会引入这些组件及数据源实现之间的紧密耦合。组件中这类代码依赖性使应用程序从某种数据源迁移到其它种类的数据源将变得非常麻烦和困难,当数据源变化时,组件也需要改变,以便于能够处理新类型的数据源。
2、解决方案
使用数据访问对象(DAO)来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便于检索和存储数据,DAO实现了用来操作数据源的访问机制。依赖于DAO的业务组件为其客户端使用DAO提供了更简单的接口,DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时,DAO向客户端提供的接口不会变化,所以该模式允许DAO调整到不同的存储模式,而不会影响其客户端或业务组件。重要的是,DAO充当组件和数据源之间的适配器。
3、实现策略
通过调整抽象工厂(Abstract Factory)模式和工厂方法(Factory Method,这二个创建型模式的实现详情可参看GoF的<设计模式>一书)模式,DAO模式可以达到很高的灵活度。
4、应用
当数据访问代码被直接嵌入到有其他不相关职责的某类中时,就会使修改变的十分困难。这时可以采用分离数据访问代码的解决方案,将数据访问代码抽取到一个新类中,并且把该新类逻辑或者物理地移动到离数据源比较近的位置,这样可以增强模块性和可重用性,如下面图3所示。具体作法可以使用提炼类(Extract Class,一种重构手法,细节可参看Martin的<重构>一书)方法创建一个新类,并将原来类中把数据访问代码移动到这个新的数据访问对象(DAO)类,使用这个新的DAO对象从控制器类中访问数据。
示例:持久性逻辑被嵌入到一个使用新DAO对象管理的持久性的某企业新DAO对象中,把持久性代码和该企业新DAO对象代码结合起来会创建脆弱的、紧密耦合的代码。当持久性代码是该企业新DAO对象的一部分时,对该持久性存储的任何改动都要求更改该新DAO对象的持久性代码。这种耦合对企业新DAO对象代码维护会带来负面的影响。下面图4为运用分离数据访问对象方法对其进行重构改进后的结果。
在15个J2EE模式中,每个模式都作用于设计模式和构架模式之间的某些方面。每个模式不是孤立存在的,需要其它模式的支持才能更加体现其含义和用处,为了最大限度的用好模式,还需要充分理解模式之间的关系。
参考文献