[转载]EJB 倡导者: 正确进行 EJB 交叉引用

EJB 倡导者: 正确进行 EJB 交叉引用


开发人员试图消除对 EJB 组件的使用可能导致的复制引用列表,破坏封装性及令人头痛的维护工作。EJB 倡导者通过展示会话 EJB 如何不只是提供分布、事务和安全性,以及它们如何帮助提高应用程序的可维护性和可靠性,从而设法缓解这些痛苦。

在每个专栏中,EJB 倡导者提出要点,客户和开发者采用独特的前后衔接的对话框方式,在对某一感兴趣的设计问题推荐解决方案的过程中进行交流。其中忽略了任何确定性的细节,并且不提供“革新的”或专有的体系架构。要了解更多信息,参见 EJB 倡导者提示

问题

亲爱的 EJB 倡导者,

我向您写这些文字的目的是希望这个对话能解决在 IBM® WebSphere® Application Server 产品变化中关于我们目前 EJB Reference 实现所遇到的问题。

一 些背景:我们的应用程序开发小组超过 1,000 人,分散在四个国家。我们目前的体系架构使用会话 EJB,使用远程接口作为多种在 POJO(plain old Java™ object,传统的 Java 对象)中实现的服务的外观。每个服务可以看作是执行一个或多个任务的工作流,这些任务本身在各自的 POJO 中为重用目的而实现(特定的任务可以在多个工作流及服务中重用)。还有,任务可以使用其他服务(例如同复杂工作流中的情形一样)。

为 了全面的权衡这种重用及我们开发组织的技术,我们通常不希望我们的程序员知道会话外观作为他们 POJO 执行环境的存在。问题是每个会话外观在部署描述符中,需要为其访问的所有会话外观分别存储一个 EJB-REF 条目。实际上,这个需求意味着由任务调用的所有服务通过给定的服务实现进行调用。并且既然我们不想破坏由给定服务调用的任务的封装性,那么这就不仅仅是维 护上让人头痛了,而且还需要我们一遍又一遍的复制引用列表。

感谢您给我们的任何帮助,特别是您是否知道某种工具能检查我们的代码并能自动为我们生成 EJB 引用。

您的,
带有 EJB Reference 问题的 Cross

深层挖掘来揭示体系架构的不一致性

仅仅是读到“由任务调用的所有服务通过给定的服务实现进行调用”EJB 倡导者本人也为此而感到头痛。这个递归指出了服务及任务的实现及使用上的不一致性——即使他们两个是分别开发的,并且可能由不同的人来实现。尽管如此,EJB 倡导者希望明确以下细节:

亲爱的 Cross,

您的体系架构看起来与我以前遇到过的许多其他由会话 bean 及帮助类处理的与工作流类似的行为相似。您的问题的解决方案可能不需要分析代码的工具,但在提出任何详细的建议之前,我希望正确的理解所有的细节。图 1 是从您的描述中我理解得出的高级体系结构。

图 1. 高级体系结构
图 1. 高级体系结构

几个问题(实际的体系结构大致同上,从左至右看):

  1. 客户端(如上图中所示的任务)是否知道他在使用远程会话 EJB,或者细节是否隐藏在某些 POJO 自身之后(像 Access bean 那样)?我问这个问题的原因是看起来您想在体系结构中完全隐藏 EJB 的使用,并且我想知道您在这方面已经做了多少工作。
  2. Task POJO 是否像我在上面展示的那样确实是 Client 的子类型?如果是,我需要确定您对上面对 Task POJO 实现应用的 #1 的回答。如果不是,我需要知道 Task POJO 是在何种情况下要访问他的方法实现中的“子”服务。
  3. Session 外观的粒度是多少?他是否是单独的方法?他是否是多个方法?我问这个问题的原因是我想知道服务是如何公开给 Client 的,而不考虑他们的实现。
  4. Service POJO 的粒度是多少?他的方法与 Session 外观是否是一对一(one-to-one)的?这个回答将告诉我您的服务的组织规则,以及我们可以预期并行开发活动的数量。
  5. Service POJO 是如何定位 Task POJO 的?是否是使用“new”操作符?是否是使用工厂(factory)模式?是否是使用单件(singleton)模式?对这个问题的回答将对现有代码的移植很重要,如果有任何需要的话。
  6. Task POJO 的粒度是多少?他是否是单独的方法?他是否是多个方法?
  7. Task POJO 是有状态的还是无状态的?我提的建议依赖于您是否使用“命令(command)”模式,如下所示:
    1. 创建任务(或从池中获得)
    2. 设置表示输入的属性
    3. 执行
    4. 取得表示输出的属性
    5. 移除他(或将其放回池中)。
    参见图 2 中的程序表。

图 2. 有状态命令模式的程序表
图 2. 有状态命令模式的程序表

就这些了,
您的 EJB 倡导者

以下是回复:

亲爱的 EJB 倡导者,

感谢您及时的答复。这里是对您的问题的回答:

  1. 客 户端使用“new”操作符创建 POJO,我们将其称为“业务代表(business delegate)”(或 BD)并使用它来隐藏取得 Home 及创建 Session 的细节。与 Session 一样,BD 也是从 Service POJO 中生成的。您认为我们试图完全对我们的程序员隐藏对 EJB 的使用是基本正确的。首先使用 EJB 已经成为我们组织内的规定了,但我们还容忍使用会话来获得远程管理、安全及事务的容器。
  2. 与其他客户端一样,Task POJO 方法的实现也是使用 BD,正如您所展示的。
  3. Session 接口有多重与某些方式有关的方法。
  4. Service POJO 的方法与 Session Bean 外观的方法是一对一的。
  5. Service POJO 的方法仅简单的使用 new() 操作符创建 Task POJO。想法是 Service 及 Task POJO 方法都是尽可能简单的“纯”Java。还有,在一定的环境下,Service POJO 方法将直接为另一个 Service POJO 新建一个 BD。我们喜欢 WebSphere 在两个 Session 外观共处一地时,将 ORB 调用“短路”的方式。
  6. 在 Task POJO 中可以有多个公共方法,但更多的经常是只有一个。或许有一些私有方法。
  7. Task POJO 方法不是有状态的,正如您在程序表中展示的那样。但是我想知道,如果我们使用您展示的命令方式的编程模型,我们的体系结构会有什么不同。

希望这些回答对您提出解决方案有帮助。

您的,
带有 EJB Reference 问题的 Cross


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


小建议:也对任务使用会话 EJB

这个回答与 EJB 倡导者所预期的基本相符,除任务不是有状态之外。无论如何,看起来问题出现在没有将任务视为成熟的组件。(格言“如果它能走路、嘎嘎叫那么它看起来像鸭子...”油然而生)。

下面是提出的建议:

亲爱的 Cross,

感谢您的回答,因为他们为我能给出解决方案提供了足够的信息。下面是修改后的类图,用到了您出于比较目的提供的一些额外信息,就此我将提出如下建议。

图 3. 修正的高级体系结构
图 3. 修正的高级体系结构

凭经验,我对代码的开发与测试独立进行表示赞同,他应该被打包成组件。让我们先假您的小组不反对 EJB。假如这样,我将推荐 Service 及 Task 都作为会话 bean 来实现。为何?因为您的小组没有注意到的会话 EJB 的好处是其可维护性及可靠性。

您要注意到 Service 及 Task 之间的一个区别是 Service 是远程访问的,而 Task 是本地访问的。因此,我提议为 Service 使用远程(Remote)接口,Task 使用本地(Local)接口,如图 4 所示。

图 4. 提议的使用远程服务及本地任务的高级体系结构
图 4. 提议的使用远程服务及本地任务的高级体系结构

如 果 Task 将有状态编程模型公开给服务(如我最先假设的那样),那么他们在 EJB 部署描述符中就可以声明为有状态的而不是无状态的。本地会话 EJB 的开销很低,所以即使他们是有状态的,性能不是问题。(另一种说法,某些人可能会争论说应该永远不要使用有状态会话 bean。然而,我们没有说过永远。我们乐意在此场合推荐他们,因为他们部署在本地 Service 当中;因此,无状态发生在开始于最外层代表 Service 会话 bean 的事务环境中。简而言之,如果您想接收位于会话外观后的本地实体 EJB,您也要接收位于其后的本地有状态会话 EJB。)在任何一种情况下,将 Task 转换为不管是否是有状态的会话 EJB 是有益处的。

当然,最大的益处是这个 体系结构解决了您的重用及 EJB-REF 问题。构建 Service 的程序员可以使用 Task(以及正如您所描述的在某些情况下的 Service)。构建 Task 的程序员可以使用 Service。在两种情况下,每个会话 bean(Task 或 Service)的部署描述符仅仅包括他所实际使用的每个会话 bean 的 EJB-REF。保持了封装,这对可维护性至关重要。

使每个 Task 都成为 EJB 的另一个益处是您可以对 Task 进行单元测试,而与调用他们的 Service 无关(包括测试他们使用的 EJB-REF)。使组件容易测试所做的任何事情对可靠性都是有好处的。

还 有,常常没有注意到的显式的基于 EJB 的方法的益处是您的业务逻辑可以利用 EJB 环境访问信息,例如用户的调用及当前活动的事务。这个能力简化了 Service 及 Task 方法的签名(我之所以没有问这个问题,是因为我假设用户 ID 及其他在会话环境中的信息是显式的传递到 Service 及 Task POJO 方法签名中的——但我们可以把这个问题保留在另一个讨论中)。

但即使说到这,我怀疑您仍不能将对 EJB 的使用显式的公开给小组。折衷的方法是生成“业务代表”并与 Task POJO 中的会话 EJB 组件相关联,如图 5 所示。

图 5. 生成业务代表并与服务及任务的 EJB 组件关联
图 5. 生成业务代表并与服务及任务的 EJB 组件关联

需要改变 Service POJO 代码新建 Task Delegate 而不是 Task POJO。但好的 IDE 将帮助简化移植过程。并且改变是物有所值,因为这个方法将帮助使体系结构在部署操作方面更加面向服务且具有更强的灵活性。

祝在您以后的努力当中好运。

就到这里了,
您的 EJB 倡导者


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


结束语

通过这次交流,我们看到了 Session EJB 的应用程序——远程的及本地的,无状态的及有状态的。有希望的一点是,当选则使用 EJB 时,除分布、安全性和事务之外,我们将可维护性和可靠性添加到了体系结构预期的收益列表中。

凭 经验来看,面向服务的体系架构需要功能分解:分解导致组件最终需要进行管理,使用会话 EJB 最佳的实现 Java 中的组件(使用或不使用帮助类,该类使会话 EJB 成为外观)。在某些地方试图隐藏 EJB 的使用(通常导致某些可调整的权衡),但试图避免使用组件是另外一回事(通常导致问题的发生)。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130633/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130633/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值