SOA代表了基于组件的应用程序发展

来源:互联网 发布:php 十进制转十六进制 编辑:程序博客网 时间:2024/05/21 09:10

  EJB 倡导者都采用独特的前后衔接的对话方式与实际客户和开发人员进行交流,并在期间针对某一大家关注的设计问题推荐解决方案。本月,EJB 倡导者发现自己处境微妙,对诸如服务组件体系结构(Service Component Architecture,SCA)等 SOA 相关规范的倡导与对 Enterprise JavaBeans™相关规范的倡导一样多。

  SOA 有什么真正的新特性?

  我对围绕面向服务的体系结构 (SOA) 的所有喧嚣感到有点迷惑——而您似乎被它迷住了。

  例如,在 EJB 倡导者: 在面向服务的体系结构中,使用无 facade 的 EJB 组件是最佳选择吗? 中,您描述了在设计 EJB 组件以使它们“面向服务”(例如,使它们成为粗粒度的或无状态的)时所应遵循的最佳实践。

  对我们这些使用诸如 CORBA 和 Enterprise JavaBeans 等分布式对象技术来构建过成功应用程序的人来说,您所描述的原理并不新鲜。我想我们一直都是“面向服务”的。

  我承认您从“面向服务”的体系结构中获得了比“分布式对象”体系结构更好的术语。但除此之外,我还有一个严肃的问题:存在任何有关 SOA 的新特性吗?明确地说,当我能够使用 Enterprise JavaBean 组件来做一切工作时,我为什么要关心新的服务组件体系结构 (Service Component Architecture) 和服务数据对象 (Service Data Objects) 规范?

  SCA 代表了服务器端的自然发展

  在给定我是 EJB 倡导者的前提下,下面的陈述可能会让您感到震惊——但是,您可以使用 EJB 组件以 Java 语言在服务器端编写任何代码,并不意味着您应该那样做。我的感受是,我们正在看到服务器端技术的自然发展,非常类似于我们在客户端所看到的 Java™ Servlet 的发展。

  不知您是否记得,Java Servlet 是作为一个基于标准 Java 的组件来引入的,以统一与特定 Web 服务器相关联的 Java API,如 Microsoft® 的 Internet Server API (ISAPI)。Java Servlet 使得 Java 程序员能够开发组件来生成动态网页,使那些网页能够与来自不同供应商的更广泛 Web 服务器一起运行。

  最常用的组件是 HttpServlets,它处理来自 HTTP 请求流中的输入和到 HTTP 响应流中的输出的所有映射详细信息,从而将程序员解放出来以集中于应用程序流程逻辑的详细信息。

  尽管这非常不错,然而用户很快发现,使用 Java 代码来生成 HTML 非常繁琐。例如,下面是 HttpServlet doGet() 方法中用于生成简单的动态“Hello world”的代码片段:

String name = request.getAttribute("name");
PrintWriter pw = request.getPrintWriter();
pw.println("<HTML>");
pw.println("<BODY>");
pw.println("<P>Hello " + name + "!</P>");
pw.println("</BODY>");
pw.println("</HTML>");

  各种“模板”语言很快开始涌现出来,使您能够在 HTML 中嵌入 Java 代码,从而使得该编程模型更加“所见即所得”(WYSIWYG,即声明式的)。标准化这些方法导致了 Java Server Page (JSP) 规范的产生。使用 JSP,您可以将 Java“scriptlet” (<%...%>) 和“表达式” (<%=…%>) 与 HTML 混合使用。例如,下面是某个 JSP 中用于显示相同的“Hello world”的代码片段:

<% String name = request.getAttribute("name"); %>
<HTML>
<BODY>
<P>Hello <%=name%>!</P>
</BODY>
</HTML>"

  仅只是消除括号、引号和分号本身就可以防止 Web 应用程序程序员的无数错误。此外,消除对编译、打包和部署 HttpServlet 组件的需要还极大地缩短了做出变更(无论是否为修否错误)所需的时间。

  但更重要的是,JSP 导致了一种体系结构变更,将呈现视图的关注点与获取数据的关注点分离。网页设计人员和应用程序程序员可以突然地一起工作,分别以更适合其角色的语言和风格来开发他们自己的组件而不会相互冲突。

  说句题外话,Enterprise JavaBeans 规范几乎是在同时出现的,以进一步分离那些关注点。添加 EJB 组件实现了 Web 应用程序的真正的模型-视图-控制器 (Model-View-Controller) 体系结构,其中模型由 EJB 组件来封装,视图由 JSP 来封装,控制器由 HttpServlets 来封装。

  遗憾的是,若要呈现任何真正有用的东西,Java scriptlet、表达式和静态 HTML 的交互可能变得相当复杂。例如,下面是用于产生订单 ID 和状态列表的代码片段:

<%
   OrderStatus orderStatus = (OrderStatus)request.getAttribute(
 "OrderStatus"
   );
   OrderData d[] = orderStatus.orders;
   int orderID = 0;
   String status = null;
   for (int i=0 ; i < d.length; i++)
   {
      orderID = d[i].orderID;
      status = d[i].status;
%>
<P>Order Id =<%=orderID%> Status =<%=status%></P>
<% } %>

  开始循环的那个 scriptlet 相当复杂。结尾的那个 scriptlet 确实简单,但是常常被遗忘(或放在了错误的位置)。在编辑 JSP 时,不存在用于捕获这个以及其他常见错误的工具(就像在 Java IDE 对“纯粹”HttpServlets 所遇到的情况一样)。

  简而言之,问题仍然在于,Java scriptlet 和表达式的正确使用对普通网页设计人员来说要求过高——对于没有接受过编程培训的人来说尤其如此。

  于是出现了自定义 JSP 标记的思想并得到了标准化,以最小化甚至消除对 Java 编程的需要。例如,IBM Software Services for WebSphere 开发了一些自定义标记,支持对嵌套结构进行迭代。这些标记与作为基础 JSP 标记库一部分来提供的 USEBEAN 和 GETPROPERTY 标记一起工作,以极大地简化逻辑,如下所示:

<JSP:USEBEAN
  ID="OrderStatus"
  CLASS="com.onlinemall.data.OrderStatusData"
  SCOPE="request"/>
<SW296:INDEXEDBEANPROPERTY
   BEAN="OrderStatus"
   PROPERTY="orders"
   VAR="order"
   TYPE="com.onlinemall.data.OrderData">
<P>Order ID=<JSP:GETPROPERTY NAME="order"
   PROPERTY="orderID"/>
Status=<JSP:GETPROPERTY NAME="order"
   PROPERTY="status"/></P>
</SW296:INDEXEDBEANPROPERTY>

  出现诸如 Struts 等框架以消除对编写 HttpServlets 的需要,这还是不久之前的事情。Struts 包括用于表单处理的丰富自定义标记集,但是还包括一个称为“Tiles”的概念,它支持声明式的页面组合。Tiles 的重要特性是能够非常容易地重新组合页面,而无需更改基础代码组件。Struts 是 Java Server Faces (JSF) 背后的灵感之一,JSF 标准化了从组件进行声明式 UI 组装的概念。

  客户端从 Java Servlet 到 JSP 到自定义标记框架再到 JSF 的发展是从过程化编程的组件的逐步偏离,后者必须编译为可解释的声明式组装的组件(或者至少在运行时进行编译)。面向组件的体系结构(Service Component Architecture,SCA)可看作是一种类似的发展,实现了服务器端组件到应用程序的声明式组装。

  您可能已经看到了类似如下的演示 SCA 组件的关系图:

  图 1. 示例 SCA 组件

  图 1. 示例 SCA 组件

  SCA 与 EJB 组件之间存在三个要记住的重要比较点:

  •   组合。对于 EJB 组件,Java 是可用于实现的唯一语言,因此服务到更大组装的所有组合都是通过 Java 以过程化的方式完成的。SCA 不仅支持 Java 作为实现语言,而且还支持业务流程执行语言(Business Process Execution Language,BPEL),后者正在扩展到处理诸如状态机、业务规则和人工任务等概念。
  •   调用。使用无状态会话 Bean 的方式不同于使用有状态会话 Bean、实体 Bean、自定义实体 Home 方法或消息驱动 Bean 的方式。明确地说,每种组件类型都有不同的方法来定位和调用其方法。SCA 组件支持客户机的公共调用模型,而与实现类型无关。
  •   数据。实体 EJB 组件从未打算成为可序列化的以供在容器和事务边界范围之外进行高效利用。因此数据传输对象 (Data Transfer Object,SDO) 的发展填补了这个空缺。SDO 组件提供了组件间数据流的公共抽象,而与范围无关。

  正是对“组合”、“调用”和“数据”选择的简化,使得 SCA 中从服务到应用程序的声明式组装的发展成为可能——就像 JSP 和自定义标记实现了 UI 的声明式组装这个趋势一样。

  总而言之,关心 SOA 的主要原因在于,它最终将使业务分析人员能够在具有最少程序员支持的情况下组合应用程序。


  EJB 组件是否会重蹈恐龙的覆辙?

  我还真的未曾考虑过客户端的声明式语言趋势可能会如何适用于服务器端。现在您更让我感到疑惑是否应该使用 EJB 组件了!

  EJB 组件更像是 DNA:进化的构件

  我在总结陈述中的最重要措辞是“最终”和“最少”。

  “最终”意味着 BPEL 的运行时解释器还需要相当长时间才能达到企业应用程序的所有方面所需要的功能和性能。例如,很可能“微流程”(旨在以单个工作单元运行的逻辑)作为 EJB 组件会执行得更好。

  “最少”则意味着,即使在 BPEL 标准已扩展到使业务分析人员能够通过声明式概念(如状态机、人工任务和业务规则)来指定逻辑时,也始终存在一些可以通过过程方式来更容易地指定的逻辑模 式。虽然可以创建某种“过程化”标记或可视编程语言,但是这并不比 Java 更简单——给定所有要输入的额外标记语法或要在组件之间绘制的线条,结果甚至可能更复杂。

  总之,减少对人工编写 EJB 组件代码的需要是可以实现的,但是复杂的企业级应用程序中可能仍然需要一些 EJB 组件。因此,应该将 EJB 组件视为构件,服务器端组件的扩展将基于这些构件。

查看原文