对象
在 UNO 中,对象是一个软件工件,具有我们可调用的方法和可获取并设置的属性。严格说来,对象提供的方法和属性由其支持的接口集指定。
接口
接口指定共同定义对象的一个方面的属性集和方法集。例如,接口
com.sun.star.resource.XResourceBundle
module com { module sun { module star { module resource {
interface XResourceBundle: com::sun::star::conainer::XNameAccess {
[attribute] XResourceBundle Parent;
com::sun::star::lang::Locale getLocale();
any getDirectElement([in] string key);
};
}; }; }; };
指定属性 Parent 以及方法 getLocale() 和 getDirectElement()。要允许重复使用这样的接口规范,可用一个接口继承一个或多个其他接口(例如 XResourceBundle 就继承了com.sun.star.container.XNameAccess 的所有属性和方法。多继承(继承多个接口的能力)为OpenOffice [OO2.0] 中的新增功能。
严格说来,在 UNO 中不需要接口属性。每个属性还可以表示为获取该属性值的方法与设置该属性值的方法的组合(或只是一个获取只读属性值的方法)。然而,至少有两个充分的理由支持我们将接口属性包括在 UNO 中:第一,目前对这种获取值与设置值的组合的需要非常普遍,这就要求额外支持。第二,有了接口属性,接口的设计者可以更好地表现一个对象不同功能之间的细微差别。对于那些不作为对象组成或结构部分的功能,可以使用接口属性,同时还保留访问核心功能所需的显式方法。
以前,一个 UNO 对象一般根据其不同方面支持许多独立接口。采用多继承接口技术,就可减少上述需要,因为一个对象现在可以只支持一个接口,该接口继承构成对象各个方面的所有其他接口。
服务
以前,术语“服务”在 UNO 中的含义模糊。从 OpenOffice [OO2.0] 起,底层概念已变得越来越清晰。遗憾的是,在 UNO 中,术语“服务”有两个不同的含义。使用术语“新式服务”来表示符合明确的 OpenOffice-[OO2.0] 服务概念的实体,而用“旧式服务”来表示仅符合以前的较模糊服务概念的实体。而在 UNO 之外的上下文中,术语“服务”仍经常使用不同的含义,这就使情况变得更为复杂。
尽管从技术上说,不需要再使用旧式服务,但 OpenOffice API 仍然广泛地使用它们,以保持向后兼容性。因此,使用 OpenOffice API 时,请准备好面对同时使用以上两个服务概念的情况。
新式服务的形式如下
module com { module sun { module star { module bridge {
service UnoUrlResolver: XUnoUrlResolver;
}; }; }; };
并指定组件上下文的服务管理器中某一特定服务名称(例如
"com.sun.star.bridge.UnoUrlResolver")下,存在支持某一特定接口(例如
com.sun.star.bridge.XUnoUrlResolver)的对象。(正式上,新式服务称为“基于单接口的服务”。)
旧式服务(正式上,称为“基于堆积的服务”)形式如下
module com { module sun { module star { module frame {
service Desktop {
service Frame;
interface XDesktop;
interface XComponentLoader;
interface com::sun::star::document::XEventBroadcaster;
};
}; }; }; };
并用来指定下列内容:
• 一般约定为,如果某个对象已证明支持某一旧式服务,则该对象可以支持该服务本身及其继承服务导出的所有接口。例如,方法 com.sun.star.frame.XFrames:queryFrames 返回一系列对象,这些对象都应支持旧式服务 com.sun.star.frame.Frame,从而支持 Frame 导出的所有接口。
• 此外,旧式服务可以指定一个或多个属性,如下
module com { module sun { module star { module frame {
service Frame {
interface com::sun::star::frame::XFrame;
interface com::sun::star::frame::XDispatchProvider;
// ...
[property] string Title;
[property, optional] XDispatchRecorderSupplier RecorderSupplier;
// ...
};
}; }; }; };
属性与接口属性相似,因为它们都描述了对象的其他功能。它们之间的主要差别在于,接口属性可以直接访问,而旧式服务的属性则通常通过一般接口(如com.sun.star.beans.XPropertySet)来访问。通常,接口属性用于表示对象的组成功能,而属性则表示其他的、更可变的功能。
• 一些旧式服务被设计为可从组件上下文的服务管理器中获得。例如,服务com.sun.star.frame.Desktop 可在组件上下文的服务管理器中它的服务名称"com.sun.star.frame.Desktop" 下被实例化。(问题是,我们无法确定给出的旧式服务是否设计为可在组件上下文中获得;使用新式服务代替,可以使该意图更为明确。)
• 其他旧式服务则设计为被其他服务继承的一般超级服务。例如,服务
com.sun.star.document.OfficeDocument 就作为所有不同种类具体文档服务(如
com.sun.star.text.TextDocument 和 com.sun.star.drawing.DrawingDocument)的一般基础。(多继承接口现在是表示这种一般基础服务的首选机制。)
• 还有一些旧式服务仅仅列出属性,而不导出任何接口。这些服务用于确定一组相关属性,而不像
其他种类的旧式服务那样指定某些对象支持的接口。例如,服务
com.sun.star.document.MediaDescriptor 就列出了可传递到
com.sun.star.frame.XComponentLoader:loadComponentFromURL 的所有属性。
属性是对象的功能,通常它不作为对象的组成部分或结构部分,因此通过一般 getPropertyValue
()/setPropertyValue() 方法而不是通过 getPrinter() 等特殊 get 方法来处理。旧式服务提供一
个特殊语法,可列出对象的所有属性。含有属性的对象只需要支持com.sun.star.beans.XPropertySet 接口就可以处理各种属性。典型的例子是字符属性或段落格
式属性。使用属性,可以通过对 setPropertyValues() 的单独调用来设置对象的多个功能,这将大
大提高远程性能。例如,段落通过它们的 com.sun.star.beans.XMultiPropertySet 接口支持setPropertyValues() 方法。