Factory模式和Singleton模式 该模式类似new是用来创建对象的使用Factory模式是为了实现面向对象的基本原则封装(Encapsulation)和分派(Delegation);将创建对象与使用对象进行分工因此在平时开发过程中尽量使用Factory模式创建对象 本例CatalogEJB中是使用Factory模式获得一个DAO的具体实例对象见上面CatalogEJB代码中注释我们看看CatalogDAOFactory的代码: public class CatalogDAOFactory { public static CatalogDAO getDAO() throws CatalogDAOSysException { CatalogDAO catDao = null; try { InitialContext ic = new InitialContext(); String className = (String) iclookup(JNDINamesCATALOG_DAO_CLASS); catDao = (CatalogDAO) ClassforName(className)newInstance(); } catch (NamingException ne) { } return catDao; } 在CatalogDAOFactory可以依据系统的配置文件动态获得DAO的方法之所以采取动态方式当然便于用户自己增加自己的DAO方式而不必修改代码只要直接修改配置文件就可以 如果在这里只需要CatalogDAOFactory产生一个实例可以采取Singleton模式Singleton的目的是控制类实例对象的创建并且允许整个程序只在一点对它进行访问Singleton本身类只能创建一个是单线程 public class CatalogDAOFactory { private static CatalogDAO catDao = null; public static CatalogDAO getIntance(){ if (catDao==null) try { InitialContext ic = new InitialContext(); String className = (String) iclookup(JNDINamesCATALOG_DAO_CLASS); catDao = (CatalogDAO) ClassforName(className)newInstance(); } catch (NamingException ne) { } } return catDao; } } 那么在CatalogEJB的调用从 dao = CatalogDAOFactorygetDAO(); 要改为 dao = CatalogDAOFactorygetIntance(); Facade模式 在EJB应用中有两个端点这一端是用户端另外一端是EJB通常在这两个端点间会增加一层用来松散两个端点之间的耦合比如在宠物店例子中考虑到不同身份的用户有不同的操作流程比如顾客注册进入后需要浏览目录下订单而商店管理者进入后需要确认或者否定订单或者检查库存这些功能需要借助Session bean和Entity bean完成 但是如果用户端直接和这些bean互动会有以下问题: 用户端必须注意和这些beans的所有有联系或互动的事情无法阻止用户端可能不恰当的使用这些beans 如果EJB的API改动那么用户端的一些代码也要修改无疑扩展性很差 即使这些beans都在同一台服务器上用户端还是用remote方式来调用它们造成网络无故拥挤 那么我们使用Facade模式来解决这个问题Facade的定义是为子系统中的一组接口提供一个一致的界面很显然我们需要为这些bean提供一个统一的对外界面如下图 在宠物店中ShoppingClientFacadeLocalEJB是面对所有用户端操作的统一界面用户端操作就不直接和那些EJB如CustomerEJB或ShoppingCartEJB有联系而是都通过ShoppingClientFacadeLocalEJB来联系的代码如下 public class ShoppingClientFacadeLocalEJB implements SessionBean {
//和CustomerEJB联系 public CustomerLocal getCustomer() throws FinderException { if (userId == null) {
} try { InitialContext ic = new InitialContext(); Object o = iclookup(java:comp/env/ejb/petstore/local/customer); CustomerLocalHome home =(CustomerLocalHome)o; customer = homefindByPrimaryKey(userId); } catch (javaxnamingNamingException nx) { } return customer; }
//和ShoppingCartEJB联系 public ShoppingCartLocal getShoppingCart() { if (cart == null) { try { InitialContext ic = new InitialContext(); Object o = iclookup(java:comp/env/ejb/cart/Cart); ShoppingCartLocalHome home =(ShoppingCartLocalHome)o; cart = homecreate(); } catch (javaxejbCreateException cx) {
} } return cart; }
} Facade模式参与者 SessionFacade (ShoppingClientFacadeLocalEJB) 提供一组操作流程 将真正工作委托到EJB的bean EJB的bean (CustomerEJB ShoppingCartEJB等等) 执行基本的商业逻辑操作 没有任何对SessionFacade的调用 这样不但可扩展性大大增强效率也提高了用户端只需要一次Remote对SessionFacade调用就可以了而SessionFacade会自动定位到与它同一台服务器的那些邻居bean(CustomerEJB ShoppingCartEJB等等)无疑减少网络拥挤提高了速度 总结 在EJB的具体使用中使用合适的设计模式不但使代码可重用性 可拓展性增强最重要的是能提高效率和速度我们知道EJB框架由于考虑大型系统中事务安全等各方面问题效率性能有所欠缺那么我们在具体问题具体应用时使用设计模式可以弥补这个问题 例如Proxy模式可以为我们在访问巨大的需要花费一定时间才能展开的对象时提供一个代理这样不会因为那个巨大对象而影响当前运行速度EJB中的那些bean很显然属于巨大对象(因为它们有反复的数据库操作这些很费时间〕 Flyweight模式是避免大量拥有相同内容的小类的开销(如耗费内存)使大家共享一个类(元类)当你要从EJB中获取一系列字符串而这些字符串中肯定有许多是重复的那么我们可以将这些重复的字符串储存在Flyweight池(pool)中以达到共享 |