EJB 最佳实践:业务委派模式 (转载自IBM中国开发者网站)

原文出处: http://www-900.ibm.com/developerworks/cn/java/j-ejb1022/index.shtml
EJB 最佳实践:业务委派模式 英文原文
内容:
业务接口模式
业务委派模式
参考资料
关于作者
对本文的评价
相关内容:
EJB best practices 系列
Java 专区中还有:
教学
工具与产品
代码与组件
所有文章
实用技巧
EJB 设计中的抽象业务、表示和应用逻辑

级别:中级

Brett McLaughlinbrett@oreilly.com
作家兼编辑,O'Reilly and Associates
2003 年 2 月

专栏图标应用程序规划中最复杂的问题之一是业务层和实现层之间的必要分隔。为了实现这一分隔,Brett McLaughlin 以业务接口(Business Interface)模式为基础,用一个类来处理业务逻辑上的 Web 层抽象。业务委派(Business Delegate)模式可以帮助您避免使应用程序难以维护和升级的耦合。

如果您从一开始就一直在学习本系列文章,那么您就知道我们一直关心的问题之一是将应用和表示逻辑与业务逻辑分隔开。例如,在第一篇技巧文章中,我们重点讨论远程对象设计的难题,特别是将 bean 的实现与其接口分隔时出现的难题。我们用业务接口模式解决了这个难题,本文中我们将再次使用这个模式。上一篇技巧文章解决了在支持用户访问实体 bean 内包含的数据的同时,又要避免那些 bean 直接暴露给应用层这两种需求之间的冲突。

在这两个例子中,通过从使用业务逻辑的代码中谨慎地抽象出业务逻辑实现来解决核心问题。正如本技巧文章将演示的,那种抽象是良好的应用程序设计的基础之一,特别是对于基于 EJB 的应用程序设计。这里,我们将再次使用业务接口模式和会话 bean 来使您的 Web 层与 Enterprise JavaBeans 组件保持松散耦合。

业务接口模式
我们以前的业务接口模式的实现允许我们提供特定于业务的接口,用于与会话 bean 交互。清单 1 显示了那个接口,在本技巧文章中我们将再次使用这个接口:

清单 1. Library 业务接口


package com.ibm.library;

import com.ibm.library.exceptions.NoSuchBookException;

import java.rmi.RemoteException;
import java.util.List;

public interface ILibrary {

      public List getBooks() throws RemoteException;
      public List getBooks(String category) throws RemoteException;

      public Book getBook(String isbn)
          throws NoSuchBookException, RemoteException;

      public boolean checkout(Book book) throws RemoteException;
      public boolean checkout(List books) throws RemoteException;

      // And so on...
}

注:Library 接口不包含任何 EJB 语义。而是将所有的实现和 EJB 细节都在实现该接口的会话 bean 内处理。现在,让我们查看一下企业应用程序的 Web 层可以如何访问 Library 接口和支持它的会话 bean:

清单 2. 使用 Library 接口


LibraryHome libraryHome =
     (LibraryHome)EJBHomeFactory.getInstance().
	    lookup("java:comp/env/ejb/LibraryHome",
                 LibraryHome.class);
ILibrary library = libraryHome.create();

清单 2 使用了另一个类,如果您从本系列一开始就学习的话,您应该熟悉这个类。通过查询 Library bean 的 home 接口,EJBHomeFactory 类进一步分隔业务和应用逻辑。然后从 home 接口获得 Library 接口的实现。

上述代码还不错 — 比起装入 JNDI 初始上下文、手工获得 home 接口,随后直接处理实体 bean,它确实有了改进。但它确实包含了一个基本的缺点:Web 层仍旧与 EJB 组件结合在一起,尤其与 Library 会话 bean 结合在一起(而不仅是业务接口)。当您需要逐渐停止使用实体 bean,而开始使用 Java 数据对象(Java Data Object),或合并 EJB 规范的一个新版本时,您的应用程序代码会怎样呢?当您觉得更喜欢清晰分隔的系统的体系结构时(这是不可避免的),会怎么样呢?尽管短期内比较容易编写紧密耦合的代码(即,将实现语义引入到业务层的代码),但这样做几乎不可避免地缩短了应用程序的使用寿命。由此产生了业务委派模式。

获得“中间人”:业务委派模式
业务委派模式与业务接口模式完全不同。尽管业务接口模式定义了可以使用的业务逻辑,但业务委派提供了对那个逻辑的访问,而不会产生与其实现技术(在本例中是 EJB 组件)的相关性。明确地讲,业务委派是一个助手类,它处理连接到 EJB 容器、获取任何所需资源以及按需释放那些资源的细节。清单 3 使用了清单 1 中的 Library 接口作为其开始点,但请注意引入的新 LibraryDelegate 类和方法。

清单 3. 用于 Library bean 的业务委派


package com.ibm.library;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.naming.NamingException;

public class LibraryDelegate implements ILibrary {

      private ILibrary library;

      public LibraryDelegate() {
          init();
      }

      public void init() {
          // Look up and obtain our session bean
          try {
              LibraryHome libraryHome =
                  (LibraryHome)EJBHomeFactory.getInstance().lookup(
                      "java:comp/env/ejb/LibraryHome", LibraryHome.class);
              library = libraryHome.create();
          } catch (NamingException e) {
              throw new RuntimeException(e);
          } catch (CreateException e) {
              throw new RuntimeException(e);
          } catch (RemoteException e) {
              throw new RuntimeException(e);
          }
      }

      public List getBooks() throws ApplicationException {
          try {
              return library.getBooks();
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public List getBooks(String category) throws ApplicationException {
          try {
              return library.getBooks(category);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public Book getBook(String isbn)
          throws NoSuchBookException, ApplicationException {

          try {
              return library.getBook(isbn);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public boolean checkout(Book book) throws ApplicationException {
          try {
              return library.checkout(book);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      public boolean checkout(List books) throws ApplicationException {
          try {
              return library.checkout(books);
          } catch (RemoteException e) {
              throw new ApplicationException(e);
          }
      }

      // And so on...

      public void destroy() {
          // In this case, do nothing
      }
}

LibraryDelegate 类中,通过将操作请求传递给会话 bean,每个方法都可以响应请求。init() 方法处理初始化和资源的收集;destroy() 方法处理资源释放。尽管很简洁,但 LibraryDelegate 仍对整个应用程序执行的方式产生相当大的影响。注意清单 2 和下面的代码段之间的区别:


ILibrary library = new LibraryDelegate();

通过引入 LibraryDelegate,您已除去了应用程序 Web 层上的所有技术相关性。这样不仅产生了更清晰、更出色的应用程序代码,而且还对应用程序进行了定位,以便更顺利地合并在其使用寿命期间出现的更改。例如,如果您在任何时候需要从使用 EJB 技术移植到使用纯 JDBC 类,那么可以简单地用新的 JDBC 类来重写您的业务委派。您的 Web 层不会知道发生了变化,也不需要重新编译。

在下一篇系列文章中,我们将详述业务委派模式的使用,进而使它更通用化。由此产生的结果将是获得更佳的代码,以及与 EJB 技术更少的相关性。

参考资料

关于作者
作者Brett McLaughlin 从 Logo 时代(还记得那个小三角吗?)就开始从事计算机工作了。他现在专门研究用 Java 和 Java 相关技术构建应用程序基础结构。过去几年他一直在 Nextel Communications 和 Allegiance Telecom, Inc. 致力于实现这些基础结构。Brett 是 Java Apache 项目 Turbine 的共同创始人之一,该项目用 Java servlet 为 Web 应用程序开发构建可重用的组件体系结构。他还是 EJBoss 项目(一个开放源码的 EJB 应用程序服务器)和 Cocoon(一个开放源码的 XML Web 发布引擎)的志愿开发人员之一。可以通过
brett@oreilly.com 与 Brett 联系。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值