1.4.2常用的IDL术语
1.4.2.1 factory接口
很多面向对象的语言都有一个构造函数用来创建并初始化一个对象。然而,构造函数创建的是本地对象,也就是说
,在程序的地址空间内调用构造函数。因此,构造函数不能用来在另一个程序中创建对象,这就是不能给IDK接口定
义构造函数的原因。
客户程序在不同的程序(服务程序)中创建对象的方法是,客户程序调用服务程序中一个现有对象的方法,并使用
该方法(在服务程序中的)来创建一个新对象。术语“factory”专门用来表示“一个对象可以用来创建另一个对象
”。用来创建对象的方法通命名为create(),或者是包含“create”的其他名字,例如:create_account()。但
这只是一个命名约定而不是必然要求。不需要其他的语法来定义factory接口或者create-style的方法了。当然了,
这些称为使用规范的IDL语法。factory接口的例子如下所示。
*****************************************************************************************************
interface Foo {
void destroy();
...
};
interface FooFactory {
Foo create(...);
...
};
*****************************************************************************************************
图1.3 factory接口实例
正如IDL接口没有构造函数一样,它同样没有析构函数。有时候何时销毁一个对象仅仅在服务程序中决定,而不需要
客户程序的任何输入。然而,如果需要客户程序控制销毁对象时,通常通过定义一个方法完成,调用该方法时销毁
对应的对象。这个方法通常命名为destroy(),但是这只是一个命名规范而不是必然要求。
1.4.2.2回调(Callback)接口
回调过程或者回调对象常用于GUI(图形用户接口)工具箱。即应用程序开发者注册一个过程或者对象给GUI运行时
工具箱,运行时在任何时候感知某些事件(例如鼠标按键或者键盘打字等。)发生时可以回调该过程或者对象。回
调对象偶尔应用于CORBA应用程序。就IDL编译器而言,回调接口(例如FooCallback,图1.4中定义)只是一个普通
的IDL接口,所以,没有特别的语法要求用来定义一个回调接口。
*****************************************************************************************************
interface FooCallBack {
void notify something has happened(...);
};
interface FooCallbackRegistry {
void register callback(in FooCallback cb obj);
void unregister callback(in FooCallback cb obj);
...
};
*****************************************************************************************************
图1.4 回调接口示例
1.4.2.3 迭代器(Iterator)接口
假设一个IDL接口有一个query()方法,该方法返回结果是一个序列(sequence)。如果返回结果中的成员项可能会非
常大的话,不推荐用一个巨大的块返回所有的结果。原因包括以下几点:
整个返回值集合可能占用几个兆甚至几个G,尽管服务程序运行的机器可能有足够的内存来保存这么大的数据量,可
能客户端运行的机器有很少的内存。一次性返回如此大的数据给客户程序可能会导致客户程序内存溢出。将查询结
果以几个小块的形式返回给客户程序不占用太多的客户程序内存将是一个更好的方法。
在很多调用查询类型(query-style)方法的客户-服务(c/s)应用程序中,查询结果显示给交互性用户,用户剪取
他/她的兴趣数据。就像经常发生的一样,如果用户碰巧能在列表的起始位置附近找到了想要的数据项,从服务端传
送所有的查询结果给客户端将浪费网络带宽还有内存。为避免这种浪费,最好分成几个小块将查询结果发给客户程
序。假如用户在查询结果的第一个或者第二个数据块找到一个数据项,后面的结果就没必要再从服务期传送给客户
了。
*****************************************************************************************************
struct Data { ... };
typedef sequence<Data> DataSeq;
interface DataIterator {
DataSeq next n items(in unsigned long how_many);
void destroy();
};
interface SearchEngine {
DataSeq query(
in string search_condition,
in unsigned long how_many,
out DataSeq results,
out DataIterator iter);
};
*****************************************************************************************************
图1.5 迭代器接口
图1.5表达了一个迭代器接口的典型应用。query()方法最初返回how_many个结果集中的数据项。如果包含了所有的
数据项,那么iter参数将设置为无对象引用。要不然,iter参数就包含一个对DataIterator对象的引用,以用来得
到更多的结果,一次一次发送how_many个数据项。当迭代器没有结果要返回时,next_n_items()返回一个空的序列
,然后客户程序调用迭代器的destroy()方法。