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 倡导者本人也为此而感到头痛。这个递归指出了服务及任务的实现及使用上的不一致性——即使他们两个是分别开发的,并且可能由不同的人来实现。尽管如此,EJB 倡导者希望明确以下细节:
亲爱的 Cross, 您的体系架构看起来与我以前遇到过的许多其他由会话 bean 及帮助类处理的与工作流类似的行为相似。您的问题的解决方案可能不需要分析代码的工具,但在提出任何详细的建议之前,我希望正确的理解所有的细节。图 1 是从您的描述中我理解得出的高级体系结构。 图 1. 高级体系结构 几个问题(实际的体系结构大致同上,从左至右看):
图 2. 有状态命令模式的程序表 就这些了, |
以下是回复:
亲爱的 EJB 倡导者, 感谢您及时的答复。这里是对您的问题的回答:
希望这些回答对您提出解决方案有帮助。 您的, |
|
这个回答与 EJB 倡导者所预期的基本相符,除任务不是有状态之外。无论如何,看起来问题出现在没有将任务视为成熟的组件。(格言“如果它能走路、嘎嘎叫那么它看起来像鸭子...”油然而生)。
下面是提出的建议:
亲爱的 Cross, 感谢您的回答,因为他们为我能给出解决方案提供了足够的信息。下面是修改后的类图,用到了您出于比较目的提供的一些额外信息,就此我将提出如下建议。 图 3. 修正的高级体系结构 凭经验,我对代码的开发与测试独立进行表示赞同,他应该被打包成组件。让我们先假您的小组不反对 EJB。假如这样,我将推荐 Service 及 Task 都作为会话 bean 来实现。为何?因为您的小组没有注意到的会话 EJB 的好处是其可维护性及可靠性。 您要注意到 Service 及 Task 之间的一个区别是 Service 是远程访问的,而 Task 是本地访问的。因此,我提议为 Service 使用远程(Remote)接口,Task 使用本地(Local)接口,如图 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 组件关联 需要改变 Service POJO 代码新建 Task Delegate 而不是 Task POJO。但好的 IDE 将帮助简化移植过程。并且改变是物有所值,因为这个方法将帮助使体系结构在部署操作方面更加面向服务且具有更强的灵活性。 祝在您以后的努力当中好运。 就到这里了, |
|
通过这次交流,我们看到了 Session EJB 的应用程序——远程的及本地的,无状态的及有状态的。有希望的一点是,当选则使用 EJB 时,除分布、安全性和事务之外,我们将可维护性和可靠性添加到了体系结构预期的收益列表中。
凭 经验来看,面向服务的体系架构需要功能分解:分解导致组件最终需要进行管理,使用会话 EJB 最佳的实现 Java 中的组件(使用或不使用帮助类,该类使会话 EJB 成为外观)。在某些地方试图隐藏 EJB 的使用(通常导致某些可调整的权衡),但试图避免使用组件是另外一回事(通常导致问题的发生)。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130633/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-130633/