﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-kapok-随笔分类-CorBa</title><link>http://www.blogjava.net/kapok/category/2617.html</link><description>垃圾桶,嘿嘿，我藏的这么深你们还能找到啊，真牛！</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 01:36:09 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 01:36:09 GMT</pubDate><ttl>60</ttl><item><title>Corba中IDL的设计</title><link>http://www.blogjava.net/kapok/archive/2005/08/08/9595.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 08 Aug 2005 10:24:00 GMT</pubDate><guid>http://www.blogjava.net/kapok/archive/2005/08/08/9595.html</guid><wfw:comment>http://www.blogjava.net/kapok/comments/9595.html</wfw:comment><comments>http://www.blogjava.net/kapok/archive/2005/08/08/9595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kapok/comments/commentRss/9595.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kapok/services/trackbacks/9595.html</trackback:ping><description><![CDATA[<CENTER>
<H3>Corba中IDL的设计</H3></CENTER><STRONG><FONT size=4><A href="http://www.huihoo.com/corba/corba_idl.html">http://www.huihoo.com/corba/corba_idl.html</A></FONT></STRONG><BR>(来源：http://www.ccw.com.cn) <BR><BR>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>从技术的角度来讲，把系统设计成n层结构需要解决系统管理上的一些问题，如网络的延时，系统的反应时间，服务的可用性，负载的管理，分布式的缓冲和分布式的垃圾回收等。而且，对于每一个能提高系统效率的新的解决方案，也会随之带来新的问题。但是这些在设计大型的分布式应用系统的技术上的问题，都可以通过使用一些基本的设计方法和技巧来加以解决。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>通过使用迭代（Iterator）的设计模式来定义idl语言，从而解决corba程序中诸如性能管理，缓冲，分布式垃圾回收等问题。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B><FONT size=4>一．性能上的问题</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>虽然corba的体系结构简化了网络的内在的复杂性。但它不能保证一定可以构造一个高</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>性能，高效率的系统，要实现这个目标，整个系统的设计一定要考虑到网络固有的结构，主要是以下的三个因素。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>1． 远程调用的数量。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>2． 数据传输的数量。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>3． 不同数据类型的转换和包装。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>如果在系统设计的开始加以考虑，这些问题将会得到解决。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>在基于corba的体统设计中，idl在组件的设计中起了很大的作用，应为它定义了服务端程序相互遵循的接口标准。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B><FONT size=4>二．IDL的设计</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>一个通常在IDL设计中被忽视的问题是哪一个接口用于服务器端的应用程序，以及暂时的（transient）和持久的（persisent）corba对象。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>1．一个服务器端的应用程序是一个用于实现对象方法的，与语言无关的对象。在corba程序的模型中，服务器端的程序通过可移植对象适配器（Portable Object Adaptor,即POA）向系统注册，从而能一直接受用户对它的调用。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>2．同服务器端的对象相比，暂时的corba对象并不用POA向系统注册，他们在用户向系统请求的过程中由服务器端的应用程序生成。这些暂时的corba对象的生命周期不会超过所在进程或生成该对象的线程的生命周期，而且他们的对象句柄并不公开。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>3．持久性的corba对象同持久性的状态相关联，有着特殊的用途。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>以下主要讨论使用暂时的corba对象来管理大量数据的传输。这个方法在处理可能丢失数据的程序时非常有用，如下例所示：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>用户要查询大量的数据，在得到了前20个数据后，另一个用户也提出一个查询，可能的情况是前面查询的数据将丢失。在一个单进程的应用程序中，这不是一个问题。但是在分布式编程和设计中。将会占用很多的网络带宽和cpu的处理时间。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>基于如上所述，图一提供了一个客户端和服务器端程序的交互相应的示意图。客户端的代理是个远端的代理类，用于处理同远端服务器程序的连接以及把客户端的请求发送到服务器端。客户端向提供所需服务的服务器端付出请求，服务器端返回一组产品的信息，如果这个结果中有n个产品，则N个元素经过参数转换后在返回。初一看，这个设计是可行的，如果不发生前面所说的不可预料的情况的话。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>
<P align=center><IMG src="http://www.huihoo.com/corba/i/01_8_20_6a.jpg" border=0> </P></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>下面的代码定义了用来实现客户端和服务器端交互作用的IDL接口和方法。该文件中只定义了一个方法，用来返回一组产品的信息。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Module productcatalog</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>struct ProductItem</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>string productName;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>…</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>typedef sequence<PRODUCTITEM> ProductItemList;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Interface ProductCatalog</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductItemList getProductItems(in string group,in string category,in string status )</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Raises {SomeRemoteException};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>从客户端的角度看，对服务器端程序的一个请求，来检索产品的信息需要如下的几步骤。如图二所示.</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>
<P align=center><IMG src="http://www.huihoo.com/corba/i/01_8_20_6b.jpg" border=0> </P></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>代理的对象提供了一个包，绑定到一个特定的服务器端的对象实例上来充当一个中间的对象，用来管理对远程服务器对象的调度了管理。它的主要任务包括：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>1． 准备一个请求</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>2． 把调用请求提交给ORB的桩(stub)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>3． 捕捉（trap）远端的异常。（最好把它们映射到用户自己定义的异常中）</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>4． 准备好用于接受特定对象模型的数据结构。这些数据要被客户端的应用程序使用产品类代理的实现如下面的代码所示：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public class ProductServiceProxy</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private static ProductServiceProxy instance;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private ProductServiceProxy() {}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public static ProductServiceClient getInstance()</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>if(instance==null)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>instance=new ProductServiceProxy();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>return instance;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public ArrayList getProducts(String group,String category,String status) </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>throws SomeException</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ArrayList productList=new ArrayList();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Try</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductService productService=LocateRemoteService();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>If(productService==null)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>//return empty list or throw user defined exception</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>try</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>//get products using criteria,when request returns data,prepare data and store </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>results in collection object</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>catch(SystemException se){//handle exception }</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>catch(Exception e){//handle exception}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>return productList;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>客户端的代理类用单一（singleton）模式来实现，从而可以保证只有一个客户端的代理对象实例生成，对于每一个需要远端调用的请求，LocateRemoteService()方法就会调用，从而来验证远端对象的句柄，如果连接已断开或者对象的句柄已经失效，就会自动绑定，从而能防止失败。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>另外的一种IDL的设计是，服务器端程序返回一系列的产品ID号而不是产品本身。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>如图三所示：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>
<P align=center><IMG src="http://www.huihoo.com/corba/i/01_8_20_6c.jpg" border=0> </P></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>就网络本身来讲，这两个设计的差别主要在于产品ID号的数据量要远远小于产品本身的数据量。而用户也可以选择其中的一个ID号来察看产品的详细信息。这个设计同前面的设计相比更趋合理。因为它能根据用户的需求来传送数据，从而不会导致大量无用数据的传输。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>但是这个设计方案也有一个弊端，即要决定是否要显示产品ID号。而检索每一产品都需要查询所有的产品信息，这样就会带来同第一个方案相同的问题。因为为了数据，需要进行n+1次的远程调用。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>第三种方案如图四所示，它主要重新设计了IDL，利用用户的习惯和系统计算的限制。这个设计上的改进主要基于如下的考虑。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>
<P align=center><IMG src="http://www.huihoo.com/corba/i/01_8_20_6d.jpg" border=0></P></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>对于很多的用户界面的应用程序来讲，如基于JAVA SWING或WEB的程序，一次现实多少数据常常会受到屏幕大小的限制。对与WEB的程序来讲，查询的结果常 常会被分为很多页，由导航栏来控制信息的显示。而且，一般来说，用户常常需要一定 的时间来浏览显示的信息，然后才会选择下一步的动作。这就给程序的运行了调用带来 了一定意见的缓冲。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>为了实现这个目的，需要运用如下的机制来规范信息的流动了传输。一个方法就是使用迭代（Iterator）设计模式.因此需要重新设计IDL，从而能使大量的数据分成多 个块来传输。为了方便程序的实现，需要首先定义一个基本的迭代接口来规定远程迭代 类的方法。下面的代码定义了一个基本的BaseIterator和BaseListIterator接口。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>/* Base Iterators in IDL */</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#include “util/exceptions/idlexceptions.idl”</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>module iterator</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>interface BaseIterator</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Boolean hasNext() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Short count() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>interface BaseListIterator</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Boolean hasPrevious() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Short previousIndex() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Boolean hasNext() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Short nextIndex() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Short count() raises(SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>/* util/iterator/iterator.idl */ </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>这两个接口为下面跟具体业务有关的接口的实现，如ProductIterator接口的实现提供了基础。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>/* 具体业务有关的接口定义，本例中为ProductIterator接口 */</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#include “util/iterator/iterator.idl”</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>module productcatalog</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>struct productItem</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>string productName;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>……</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>typedefsequence<PRODUCTITEM> ProductItemList;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>interface ProductIterator : iterator::BaseListIterator</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductItem next() raises (SomeRemoteException); </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductItemList nextBlock(in short size) raises (SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductItem previous() raises (SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductItemList previousBlock(in short size) raises (SomeRemoteException);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>interface ProductCatalog</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductIterator getProductItems(in string group,in string category,in string status)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>raises (SomeRemoteException); </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>};</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>值得注意的是，在上面的代码中，ProductCatalog接口中的getProductItems方法返回的是ProductIterator而不是先前的ProductItemList;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>在服务器端，实现ProductIterator的类在管理数据传输的过程中起到了集成的作用。而且从本质上来讲，ProductIterator接口是个暂时的（transient）corba对象，在调用getProductItems()的过程中生成。之所以是暂时的，是因为它的内容有查询的结果决定。如果查询后返回的结果是集合型的或者通过如ArrayList的集合类返回，则ProductIterator的实现就比较简单，因为ArrayList类本身就已经提供了了ListIterator和Iterator。另外一个就是在服务器端程序实现ProductCatalog上。GetProductItems方法返回ProductIterator对象的句柄，而不是 方案一中的Product IDs和方案二中的Products.由于Product和Product ID都是Corba的数据类型，因此服务器端的程序需要进行数据类型的映射和转换。而在方案三中，由于使用了ProductIterator,数据类型的映射就由服务器端的对象实现来决定了。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>在客户端，代理程序发起初始的请求，同时缓存了远端的迭代（Iterator）类的句柄。代理程序也可以在返回之前立刻得到下面的N个数据。图五列出了客户端和服务器端组件的交互作用的过程。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><IMG src="http://www.huihoo.com/corba/i/01_8_20_6e.jpg" border=0> </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>当客户端初始化一个请求时，客户端的代理程序首先检查缓冲中是否已经存在该请求的结果。如果缓冲中没有相关的信息，代理就会向服务器发出查询请求。查询的结果是个远端的Iterator（一个corba对象的句柄），并保存在客户端的代理中。接下来的客户端请求将会检索一个或一堆的产品信息。当然，你也可以把产品信息保存在缓冲区。当初始化一个新的查询时，你也可以先清除掉缓冲中的信息。下面的代码重新定义了实现了ProductServiceProxy接口。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Public class ProductServiceProxy</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private int nItems=15;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private ProductIterator remoteIterator;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private static ProductServiceProxy instance;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>private ProductServiceProxy() {}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public static ProductServiceClient getInstance()</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>if(instance==null)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>instance=new ProductServiceProxy();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>return instance;</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public ArrayList getProducts(String group,String category,String </TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>status) throws SomeException</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ArrayList ProductList = new ArrayList();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>Try</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ProductService productService= locateRemoteProductService();</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>If(productService==null)</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>//return empty list or throw user defined exception</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>try</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>remoteIterator=productService.getProducts(…..);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>catch(SystemException se){//handle exception}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>catch(Exception e){//handle exception}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>return this.getMoreProducts(nItems);</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>public ArrayList getMoreProducts(int nItems) throws SomeException</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>{</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>//retrive the next 10-15 items using cache iterator</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>…</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>}</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>由于远端的迭代类（Iterator）是个暂时的CORBA对象，它要依赖于服务器端程序生命周期。因此，系统的设计一定要保证在客户端程序完成之前，该对象一定要存活。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B><FONT size=4>三．结论。</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>企业级应用程序的设计比较复杂。前期的设计对以后系统的性能会有很大的影响。而在CORBA环境中，IDL的设计就显得尤为重要。好的IDL设计，充分利用JDK的API，如计时器，垃圾回收机制，集合框架能大大的提高系统的性能。从而能构造一个强壮的，高度可用的分布式系统。</TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/kapok/aggbug/9595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kapok/" target="_blank">笨笨</a> 2005-08-08 18:24 <a href="http://www.blogjava.net/kapok/archive/2005/08/08/9595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IDL Basis</title><link>http://www.blogjava.net/kapok/archive/2005/08/08/9591.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 08 Aug 2005 10:05:00 GMT</pubDate><guid>http://www.blogjava.net/kapok/archive/2005/08/08/9591.html</guid><wfw:comment>http://www.blogjava.net/kapok/comments/9591.html</wfw:comment><comments>http://www.blogjava.net/kapok/archive/2005/08/08/9591.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kapok/comments/commentRss/9591.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kapok/services/trackbacks/9591.html</trackback:ping><description><![CDATA[<H1 class=SECT1><A href="http://www.huihoo.org/orbit/gnome_corba/idl-basics.html">http://www.huihoo.org/orbit/gnome_corba/idl-basics.html</A></H1>
<H1 class=SECT1><A name=IDL-BASICS>IDL 基础</A></H1>
<DIV class=SECT2>
<H2 class=SECT2><A name=IDL-BASICS-MISC>IDL 模块和接口</A></H2>
<P><FONT size=3>在任何项目中(亦或名字空间中)都可能存在大量的 CORBA 对象，如果所有这些对象需要有唯一的名字那么一定会有名字空间冲突。所以 IDL 允许定义模块(module)，模块指定一个独立的名字空间，类似于 C++ 的名字空间的功能性。现在对于任何接口都可以指定模块，就象下面例子展示的那样：</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {};
        interface Orange {};
};
      </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>在这里，我们在 FruitsBasket 模块中定义了两个对象： Apple 和 Orange。如果我们要从其他模块中引用一个对象，我们必须给出完全的对象引用，例如，从 VegetablesBasket 模块中引用&nbsp; Apple 要这样做：FruitsBasket::Apple。</FONT> </P>
<P><FONT size=3>也可能重新打开同一个模块来增加接口定义：下面的例子严格的等价于上一个。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {};
};

module FruitsBasket {
        interface Orange {};
};
      </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>IDL象 C++ 一样也有预编译宏指令(directive): 支持 #include 和 #pragma (这些宏指令由 idl-compiler 展开)。 #include 同在 C/C++ 中有类似的语义。允许你出于清晰的目的而把在同一个模块中的不同的接口分隔在不同的文件中。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>/* 这是一个 C 式样的注释 */
// 这是一个 C++ 式样的注释 : 两者都有效 
// 这些代码在 apple.idl 文件中

#include "orange.idl"
module FruitsBasket
        interface Apple {};
};
      </PRE></TD></TR></TBODY></TABLE>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>// 这些代码在 orange.idl 文件中
module FruitsBasket
        interface Orange {};
};
      </PRE></TD></TR></TBODY></TABLE></DIV>
<DIV class=SECT2>
<H2 class=SECT2><A name=IDL-BASICS-TYPES>IDL 类型</A></H2>
<P><FONT size=3>因为 IDL 的主要目的是实现在不同的语言、机器和操作系统之间的可移植性，他是强类型的。这里是最基本(标准)的 CORBA 类型:</FONT> </P>
<DIV class=TABLE>
<P><B><FONT size=3>表 1-1. 基本 CORBA 类型</FONT></B></P>
<TABLE class=CALSTABLE border=1>
<THEAD>
<TR>
<TH vAlign=top align=left width="33%"><FONT size=3>类型</FONT></TH>
<TH vAlign=top align=left width="67%"><FONT size=3>意义</FONT></TH></TR></THEAD>
<TBODY>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>short</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>16 bit signed integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>unsigned short</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>16 bit unsigned integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>long</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>32 bit signed integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>unsigned long</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>32 bit unsigned integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>long long</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>64 bit signed integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>unsigned long long</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>64 bit unsigned integer</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>float</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>32 bit IEEE float</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>double</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>64 bit IEEE float</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>long double</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>128 bit float</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>boolean</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>boolean value: TRUE or FALSE</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>octet</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>8 bit byte</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>char</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>8 bit character (ISO latin-1)</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>wchar</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>国际字符格式. FixMe: 谁知道这个格式?</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>string</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>基于 char 的字符串</FONT></TD></TR>
<TR>
<TD vAlign=top align=left width="33%"><FONT size=3>wstring</FONT></TD>
<TD vAlign=top align=left width="67%"><FONT size=3>基于 wchar 的字符串</FONT></TD></TR></TBODY></TABLE></DIV>
<P><FONT size=3>它们的使用是非常率直的: 这有一些使用了字符串和浮点类型的 IDL 接口声明:</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {
                attribute string color;
        };
        interface Orange {
		        attribute float size;
        };
};</PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>每个对象得到一个浮点类型或字符串类型的属性。</FONT> </P>
<P><FONT size=3>有赖于const 修饰(就象在 C++ 中) IDL 允许你定义常量。这里有一些样例 IDL 代码:</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {
                attribute string color;
                const float weight = 2.3;
                const string type = "sample type";
        };
        interface Orange {
                attribute float size;
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>使用 typedef 关键字就可以定义你自己的类型(还是很象在 C 和 C++ 中)。又是一个样例代码，这里定义了一个有自定义的类型属性的 Apple 对象，自定义的类型是一个字符串。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        typedef string fruit_type;

        interface Apple {
               attribute fruit_type type; 
        };

        interface Orange {
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>我们也有标准的 C/C++ 结构，枚举和阵列。结构，枚举和定长(fixed size)阵列象 typedef 一样简直就是 C 代码：</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module calendar {
        enum a_month {
                january, february, march, april, may, june, 
                july, august, september, october, december
        };

        enum a_day {
                monday, tuesday, wednesday, thursday, 
                friday, saturday, sunday
        };

        typedef long a_year;
        struct a_date {
                a_day    the_day;
                a_month  the_month;
                a_year   the_year;
        };

        interface calendar {
                attribute a_date the_date;

                // 一维阵列
                typedef a_date a_date_array[20];
                attribute a_date_array the_date_array;

                // 二维阵列
                typedef a_date_array a_date_array_multi[20]; 
                attribute a_date_array_multi the_date_array_multi;
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>变长(Variable-size)阵列在 CORBA 中叫序列(sequence):</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module calendar {

        interface calendar {
                /* 定义了一个一维 long 阵列(数组)
                 * 最大长度是 20. 
                 */
                typedef sequence &lt;long,20&gt; array_1;
                // 一个无边界的(unbounded)的一维字符串阵列
                typedef sequence &lt;string&gt; array_2;

                // 更复杂的: 一个序列的序列
                // 用于模拟多维变长阵列
                typedef sequence &lt;sequence &lt;long,20&gt; &gt; array_3;
        };
};
        </PRE></TD></TR></TBODY></TABLE></DIV>
<DIV class=SECT2>
<H2 class=SECT2><A name=IDL-BASICS-OBJECTS>IDL 方法</A></H2>
<P><FONT size=3>所有这些标准的类型允许编程者定义对象的属性和方法。对象方法(函数)这样声明：</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {

                // eat_me 方法的声明
                // 有一个 boolean 变量作为参数
                void eat_me (in boolean eat_yes_or_not );

                // 返回 Apple 是否被吃了
                boolean eaten ();

                // 返回 Apple 是否被吃了
                // 和吃它的人的姓和名     
                boolean who_ate ( out string who_surname, out string who_name );
        };
};
      </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>除了 in 修饰，这些声明非常象 C++ 代码: 参数由 in, out, inout 三种类型之一来修饰。它们的语义如下：in 参数是客户向对象发送的数据，out 参数是对象向客户发送的数据，inout 参数先从客户发送到对象，再被返回给客户。</FONT> </P>
<P><FONT size=3>所有这些方法声明都是同步操作，就是说，使用这些方法意味着你的程序将等到对象应答之后才继续执行。可以定义异步的方法，这样的话调用方法的程序可以继续执行而不是在对象返回应答之前一直阻塞，异步方法的声明用关键字 oneway(单向)。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
        interface Apple {
                // eat_me 方法的声明
                // 有一个 boolean 变量作为参数
                void eat_me (in boolean eat_yes_or_not );

                // 返回 Apple 是否被吃了
                // 异步方法
                oneway boolean eaten ();

                // 返回 Apple 是否被吃了
                // 和吃它的人的姓和名     
                boolean who_ate ( out string who_surname, out string who_name );
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>也可以定义例外(exception)(类似于 C++ 的例外类)。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitBasket {

        exception no_more_fruits {
                string reason;
        };

        interface Apple {
                // 我们所希望的各种的方法
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>最终，可以象下面这样声明有能力引发(throwing)例外的方法。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {

        exception no_more_fruits {
                string reason;
        };

        interface Apple {
                void eat_me (in boolean eat_yes_or_not ) raises ( no_more_fruits );
                // 我们所希望的诸如此类的方法
        };
};
        </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>象 C++ 的类(或 Java 的接口)，接口可以从其他的接口继承，并且支持多继承(multiple inheritance)。语法类似于 C++ 的语法。一个重要的不同是 IDL 不支持重载或不同的方法可以有相同的名字和不同的参数说明(signature)。</FONT> </P>
<TABLE width="100%" bgColor=#e0e0e0 border=0>
<TBODY>
<TR>
<TD><PRE class=PROGRAMLISTING>module FruitsBasket {
	         
        exception no_more_fruits {
                string reason;
        };

        interface generic_fruit {
                void eat_me (in boolean eat_yes_or_not ) raises (no_more_fruits);
                oneway boolean eaten ();
        };

        interface generic_fruit_one {
                boolean who_ate ( out string who_surname, out string who_name );
        };

        interface Apple : generic_fruit, generic_fruit_one {
                // 这里是特定于 Apple 的方法
        };
};
      </PRE></TD></TR></TBODY></TABLE>
<P><FONT size=3>我们展示了各种 IDL 类型，一些生成新的接口和属性、方法、例外的声明的方式。感兴趣的读者可以从 CORBA 标准中读到权威的 IDL 定义并且看到一些补充的类型象 any、TypeCode、union。但这些类型对于本文不是很重要的。</FONT> </P></DIV><img src ="http://www.blogjava.net/kapok/aggbug/9591.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kapok/" target="_blank">笨笨</a> 2005-08-08 18:05 <a href="http://www.blogjava.net/kapok/archive/2005/08/08/9591.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>