以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 Java/Eclipse 』 (http://bbs.xml.org.cn/list.asp?boardid=41) ---- 设计模式在EJB中的应用 (http://bbs.xml.org.cn/dispbbs.asp?boardid=41&rootid=&id=15233) |
-- 作者:npuhetao -- 发布时间:3/8/2005 10:47:00 AM -- 设计模式在EJB中的应用 什么是设计模式 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。 GoF的“设计模式”是第一次将设计模式提升到理论高度,并将之规范化,本书提出了23种基本设计模式,自此,在可复用面向对象软件的发展过程中,新的大量的设计模式不断出现。 设计模式和框架 框架通常定义了应用体系的整体结构 类和对象的关系等等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。框架主要记录软件应用中共同的设计决策,框架强调设计复用,因此框架设计中必然要使用设计模式. 另外,设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发者如果突然接触EJB J2EE等框架,会觉得特别难学,难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器。 EJB中的设计模式 EJB是采取多层结构,原先我们数据库开发基本是应用程序(商业逻辑运算)直接调用数据库驱动,在EJB中,为将商业逻辑计算和数据库截然分开,使用多个结构式模式:Adapter模式和Bridge模式等.这样做的好处显然有三个: 1.分离了商业逻辑层和数据访问层; EJB中将对数据库进行调用(如发出select等语句)称为会话bean(Sessionbean),而将对应数据库一个个记录的bean称为实体bean(Entity bean);由这两种类型的bean完成对数据库的访问. 会话bean一般和客户端应用是一一对应,而和数据库端联系紧密的是实体bean,EJB在实体bean(或直接在会话bean)和数据库之间使用了Adapter模式和Bridge模式,无意在实体bean和数据库之间又多了一层,称之为DAO(Data Access Object ),DAO实际就是设计模式的混合体. 我们以Java的宠物店中的Catalog为例,这是专门处理宠物店中的宠物类别,在对数据库访问中,有两个主要程序:CatalogEJB和CatalogDAO,我们从具体代码中看看设计模式是怎么应用的. Bridge模式和Adapter模式 public class CatalogEJB implements SessionBean { //从DAO工厂中获取一个DAO 这是调用工厂(factory)模式的一个实例 ....
}
我们发现在CatalogEJB中并没有通常的会话bean那样有对数据库操作的"select .. from ."等之类SQL操作语句,这些都被封装到DAO的具体实现中(Concrete class). 在Catalog这个示例中使用了设计模式的Bridge模式,判断是否是某种模式,主要依据其参与者的种类和相互关系,我们先看看Bridge模式的定义和参与者: Bridge模式是将抽象和行为划分开来,各自独立,但能动态的结合起来(好象搭建了一座桥)。在本例中,是将商业逻辑和数据库访问这样的行为划分开来,数据库访问专门放置在DAO中了。 Bridge模式需要两个接口(抽象类和接口通称为接口),一个用来封装抽象部分,本例中是封装商业逻辑,是CatalogEJB;还有一个是封装行为(Implementor),本例中是CatalogDAO,看看CatalogDAO代码: public Category getCategory(String categoryID, Locale l) public Page getCategories(int start, int count, Locale l) public Product getProduct(String productID, Locale l) public Page getProducts(String categoryID, int start, int count, Locale l) public Item getItem(String itemID, Locale l) public Page getItems(String productID, int start, int size, Locale l) public Page searchItems(String query, int start, int size, Locale l) Bridge模式中参与者还需要有行为接口的具体实现(ConcreteImplementor),在本例中是CatalogDAOImpl,虽然在目前宠物店中只有一个ConcreteImplementor,但是可扩展为到Mysql XML等数据源访问,比如你可以自己新增一个叫CatalogDAOImplMysql,也是作为CatalogDAO的子类。 看看CatalogDAO的一个子类CatalogDAOImpl的代码: public class CatalogDAOImpl implements CatalogDAO { //具体Select语句在这里出现,这里主要是Oracle 数据库的访问语句 public Category getCategory(String categoryID, Locale l) Connection c = null; try { ps = c.prepareStatement("select a.catid, name, descn " c.close(); } Bridge模式参与者总结如下: 商业逻辑抽象类 (CatalogEJB) 抽象的商业逻辑操作. 对数据源的抽象操作行为. 实现具体的DAO接口内容. 提供访问具体数据库的驱动接口,如包括连接池等. 很显然,如果你对Bridge模式和Adapter模式熟悉,那么对宠物店中的Catalog理解就会非常快,同样,在宠物店其他部分如订单 用户注册 等都能迅速理解。 Factory模式和Singleton模式 本例CatalogEJB中是使用Factory模式获得一个DAO的具体实例对象,见上面CatalogEJB代码中注释。我们看看CatalogDAOFactory的代码: public class CatalogDAOFactory { CatalogDAO catDao = null; }
在CatalogDAOFactory可以依据系统的配置文件,动态获得DAO的方法,之所以采取动态方式,当然便于用户自己增加自己的DAO方式,而不必修改代码,只要直接修改配置文件就可以。 如果在这里只需要CatalogDAOFactory产生一个实例,可以采取Singleton模式,Singleton的目的是控制类实例对象的创建,并且允许整个程序只在一点对它进行访问。Singleton本身类只能创建一个,是单线程。
public class CatalogDAOFactory { public static CatalogDAO getIntance(){ } }
那么在CatalogEJB的调用从 Facade模式 但是如果用户端直接和这些bean互动,会有以下问题: 那么我们使用Facade模式来解决这个问题,Facade的定义是为子系统中的一组接口提供一个一致的界面,很显然我们需要为这些bean提供一个统一的对外界面。如下图:
在宠物店中,ShoppingClientFacadeLocalEJB是面对所有用户端操作的统一界面,用户端操作就不直接和那些EJB如CustomerEJB或ShoppingCartEJB有联系,而是都通过ShoppingClientFacadeLocalEJB来联系的。代码如下: public class ShoppingClientFacadeLocalEJB implements SessionBean { //和CustomerEJB联系 return customer; ..... //和ShoppingCartEJB联系 .... }
Facade模式参与者: SessionFacade (ShoppingClientFacadeLocalEJB) 提供一组操作流程 执行基本的商业逻辑操作 这样不但可扩展性大大增强,效率也提高了,用户端只需要一次Remote对SessionFacade调用就可以了,而SessionFacade会自动定位到与它同一台服务器的那些邻居bean(CustomerEJB, ShoppingCartEJB等等),无疑减少网络拥挤,提高了速度. 总结 例如Proxy模式可以为我们在访问巨大的需要花费一定时间才能展开的对象时,提供一个代理,这样不会因为那个巨大对象而影响当前运行速度,EJB中的那些bean很显然属于巨大对象(因为它们有反复的数据库操作,这些很费时间〕。 Flyweight模式是避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类).当你要从EJB中获取一系列字符串,而这些字符串中肯定有许多是重复的,那么我们可以将这些重复的字符串储存在Flyweight池(pool)中以达到共享。 |
-- 作者:xmzhy -- 发布时间:3/10/2005 11:05:00 AM -- ding |
-- 作者:npuhetao -- 发布时间:3/10/2005 3:34:00 PM -- 谢谢,看帖并回帖是个好习惯! |
-- 作者:JamesSam -- 发布时间:4/20/2005 3:19:00 PM -- good |
-- 作者:metago -- 发布时间:4/21/2005 5:57:00 PM -- 这个很有意思,希望帅哥继续努力啊! |
-- 作者:herry -- 发布时间:5/1/2005 11:11:00 PM -- 不错!谢谢! |
-- 作者:lovewh -- 发布时间:6/18/2005 10:08:00 PM -- 学习 |
-- 作者:binaryluo -- 发布时间:6/19/2005 11:29:00 PM -- up |
-- 作者:yule -- 发布时间:8/13/2005 4:47:00 PM -- up |
-- 作者:lywzd -- 发布时间:11/2/2005 5:15:00 PM -- 可以啊,原创!!好. |
-- 作者:flyfoxs -- 发布时间:11/9/2005 10:15:00 PM -- 改天我也写一点出来,最近一直在看设计模式的东西!!! |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
109.375ms |