《组件技术最后一讲》由会员分享,可在线阅读,更多相关《组件技术最后一讲(41页珍藏版)》请在金锄头文库上搜索。
1、组件技术组件技术最后一讲最后一讲潘爱民北京大学计算机科学技术研究所http:/ overviewvv复习frameworkvv领域工程领域工程 单个系统单个系统 一类系统一类系统 针对应用的抽象针对应用的抽象vv组件组件库库vv提供定制功能,允许开发人员对于框架主体部提供定制功能,允许开发人员对于框架主体部分进行修改分进行修改vv不同层次上的不同层次上的frameworkframework 基于二进制代码的基于二进制代码的frameworkframework,例如例如MMCMMC 基于源代码的基于源代码的frameworkframework,例如例如MFCMFC基于二进制的基于二进制的fram
2、eworkvv接口:接口: 为应用中的组件提供二进制接口为应用中的组件提供二进制接口vv以对象形式封装以对象形式封装vv以功能为单位以功能为单位 粒度粒度vv大而全的接口大而全的接口vv小型接口,允许动态发现新的接口小型接口,允许动态发现新的接口vv通信模型通信模型 用户组件与框架进行通信用户组件与框架进行通信 用户组件之间如何通信?用户组件之间如何通信?vv通过框架传递信息通过框架传递信息vv通过框架建立直通模型通过框架建立直通模型基于源代码的基于源代码的frameworkvv接口:接口: 一般为抽象类,用户提供虚函数的实现,并注册到一般为抽象类,用户提供虚函数的实现,并注册到主框架中主框架
3、中 用户定制的余地比较大用户定制的余地比较大vv通信模型通信模型 用户组件与框架进行通信用户组件与框架进行通信 用户组件之间容易建立起直通途径用户组件之间容易建立起直通途径从派生类传播类型到基类的一种模式从派生类传播类型到基类的一种模式vv意图:意图: 基类有时需要根据子类的类型执行一些功能,而基基类有时需要根据子类的类型执行一些功能,而基类又不可能直接得到子类的静态类型类又不可能直接得到子类的静态类型 这对于这对于generic programminggeneric programming非常重要,因为编译器非常重要,因为编译器要靠静态类型来实例化模板要靠静态类型来实例化模板( (函数或者类
4、函数或者类) )vv解决方案解决方案 用虚函数不能解决问题用虚函数不能解决问题 runtimeruntime多态性多态性 在子类中插入一个函数,由该函数调用模板函数或在子类中插入一个函数,由该函数调用模板函数或者模板类,或者该函数调用基类中的模板成员函数者模板类,或者该函数调用基类中的模板成员函数 仅对基于源代码的仅对基于源代码的frameworkframework适用适用Framework举例举例vv为报社提供一套frameworkSnap-In管理器FrameSiteFrameSiteFrameSiteSnapIn对象SnapIn对象SnapIn对象Security管理器Database管
5、理器UI管理器SnapIn仓库IFrameSiteISnapInfoSnapIn DLLSnapIn DLLSnapIn DLL可重用类库的设计可重用类库的设计(一一)vv在所有的系统设计中,可重用类库的设计是难度比较在所有的系统设计中,可重用类库的设计是难度比较大的,要做到:大的,要做到: 使用:灵活性和易用性使用:灵活性和易用性 功能:广泛性和效率功能:广泛性和效率vv经验非常重要经验非常重要 实现同样的功能会有许多不同的道路,如何选择?效果怎么实现同样的功能会有许多不同的道路,如何选择?效果怎么样?样?vv类库的基础类库的基础 是否使用其他的类库?是否使用特殊的平台和编译环境?是否使用其
6、他的类库?是否使用特殊的平台和编译环境?vv参考成功的类库参考成功的类库 起点要高起点要高可重用类库的设计可重用类库的设计(二二)vv接口的设计接口的设计 这是类库的关键,会影响到类库的使用这是类库的关键,会影响到类库的使用vv接口的类型:接口的类型:C/C+C/C+ 大而全的接口并不理想大而全的接口并不理想 接口的语义一定要清晰接口的语义一定要清晰 facadefacade模式模式vv内存管理内存管理 保证内存分配和释放的一致性保证内存分配和释放的一致性 使用要方便使用要方便vv outout参数的资源由谁来申请?谁知道参数的资源由谁来申请?谁知道sizesize?vv是否使用自定义的内存分
7、配器,例如针对小对象的分配器是否使用自定义的内存分配器,例如针对小对象的分配器可重用类库的设计可重用类库的设计(三三)vv使用各种模式使用各种模式 模式是经验,成功的典范模式是经验,成功的典范 policypolicy模式允许使用者定制类模式允许使用者定制类 结构型模式有助于建立起更加合理的结构模型,而结构型模式有助于建立起更加合理的结构模型,而不至于层次错综复杂不至于层次错综复杂 行为型模式有助于各个类之间有更好的协作模型行为型模式有助于各个类之间有更好的协作模型 创建型模式可以提供各种合理的创建机制创建型模式可以提供各种合理的创建机制vv模板类库的特殊性模板类库的特殊性 利用模板类型实现利
8、用模板类型实现compile-timecompile-time的预处理的预处理 熟悉编译器的特性熟悉编译器的特性 控制模板生成代码控制模板生成代码可重用类库的设计可重用类库的设计(四四)vv行为前置和延后行为前置和延后 在基类中提供缺省的实现在基类中提供缺省的实现 纯虚函数纯虚函数 强制子类提供实现强制子类提供实现 利用利用functorfunctor或者函数指针或者函数指针 要求要求( (必须必须) )子类调用父类的实现子类调用父类的实现vv用宏来封装代码用宏来封装代码vv代码风格代码风格vv类库的优化类库的优化 优化需要用到内部知识,是否暴露这些知识优化需要用到内部知识,是否暴露这些知识
9、允许使用者用允许使用者用policypolicy进行配置,用不同的实现配置类进行配置,用不同的实现配置类 类似于类似于policypolicy的思想,在细节点上用开关进行控制的思想,在细节点上用开关进行控制可重用类库的设计可重用类库的设计(五五)vv类库的调试类库的调试 类库内部调试,使用类库内部调试,使用assertassert支持支持vv类库的测试类库的测试 比应用系统的测试更加严格比应用系统的测试更加严格vv类库的发行类库的发行 是否提供源代码?是否提供源代码? 文档文档 编译设置编译设置可重用类库的设计可重用类库的设计(六六)vv举例:举例:MFC/ATLMFC/ATLvvMFCMFC
10、 同时也具有源代码框架的结构同时也具有源代码框架的结构 传统意义上的传统意义上的C+C+类库,对类库,对Win32Win32进行了封装进行了封装 以便于使用为主要目标,优化较少以便于使用为主要目标,优化较少 用到了许多用到了许多patternspatterns,吻合吻合WindowsWindows应用模型应用模型 涉及到许多类库设计技术涉及到许多类库设计技术 与与WizardWizard结合产生基本代码结合产生基本代码vvATLATL 用到了用到了generic programminggeneric programming中许多新的技术中许多新的技术 模板技术模板技术 优化比较突出优化比较突出
11、CORBA OverviewvvORB(Object Request Broker )vvInterface Definition Language (IDL)vvCORBA Communications Model: IIOPvvCORBA Object Model: IORvvCORBA Clients and Serversclient stubs and server skeletonsclient stubs and server skeletonsvvCORBAservices and CORBAfacilitiesCORBA结构结构CORBA Specification over
12、viewvvOMG IDLOMG IDLvvInterface:Interface: ORB InterfaceORB Interface、DII/DSIDII/DSI、Interface RepositoryInterface RepositoryvvPOAPOAvvInteroperabilityInteroperability GIOPGIOP、IIOPIIOP、IORIORvvMappingMapping COMCOM、AutomationAutomation C mappingC mapping、C+ mappingC+ mapping、SmallTalkSmallTalkvvSer
13、vice Specification(Service Specification(单独的文档单独的文档) ) naming servicenaming service、event serviceevent service、transaction servicetransaction service、security security serviceservice、trade servicetrade service、OMG IDLvv类类C C风格的语言风格的语言vv定义接口定义接口: interface: interfacevv基本数据类型基本数据类型 voidvoid、booleanboo
14、lean、charchar、wcharwchar、octetoctet、 (unsigned) short(unsigned) short、(unsigned) long(unsigned) long、(unsigned ) (unsigned ) long longlong long、floatfloat、doubledouble、long doublelong double、stringstring、anyanyvv常数、常量表达式常数、常量表达式vv构造数据类型构造数据类型 typedeftypedef、enumenum、structstruct、unionunion、数组、数组、seq
15、uencesequenceOMG IDL(续续)vvInterfaceInterface,例如:,例如:interface Account interface Account void deposit( in unsigned long amount ); void deposit( in unsigned long amount ); void withdraw( in unsigned long amount ); void withdraw( in unsigned long amount ); long balance(); long balance();vv接口方法中参数的方向属性接
16、口方法中参数的方向属性vv异常:用户自定义异常和系统异常异常:用户自定义异常和系统异常vvonewayoneway操作操作vvmodulemodule、includeincludevv允许多重继承,与实现允许多重继承,与实现( (implementation)implementation)无关无关C+ mappingvv基本数据类型与基本数据类型与C+C+的对应关系的对应关系 特殊标识符的处理特殊标识符的处理 module module namespacenamespace IDLIDL类型类型CORBA:CORBA:中的数据类型中的数据类型 字符串处理不用字符串处理不用newnew、dele
17、tedelete,而用专门的函数而用专门的函数vv枚举类型枚举类型vv复合类型复合类型 除了类型本身外,另生成一个除了类型本身外,另生成一个_ _varvar类型类型( (类似类似auto_auto_ptrptr) )vv接口类型接口类型 _ _ptrptr类型、类型、_ _varvar类型类型客户端客户端C+ mappingvv客户通过客户通过stubstub调用对象的方法调用对象的方法 客户如何得到对象引用客户如何得到对象引用 客户如何调用对象方法客户如何调用对象方法客户端客户端C+ mappingvv客户通过客户通过ORBORB接口获得初始的对象引用接口获得初始的对象引用 首先初始化首先
18、初始化ORBORB并获得并获得ORBORB接口接口 然后利用字符串形式的引用获得内部的对象引用然后利用字符串形式的引用获得内部的对象引用intint main( main( int argcint argc, char *, char *argvargv ) ) / ORB initialization / ORB initialization CORBA:ORB_ CORBA:ORB_varvar orb = orb = CORBA:ORB_initCORBA:ORB_init( ( argcargc, , argvargv, local-orb );, local-orb ); CORBA
19、:Object_ CORBA:Object_var objvar obj = = orb-string_to_objectorb-string_to_object( ( argvargv1 );1 ); Account_ Account_varvar client = client = Account:_narrowAccount:_narrow( ( objobj ); ); client-deposit( 700 ); client-deposit( 700 ); client-withdraw( 250 ); client-withdraw( 250 ); coutcout Balanc
20、e is balance() Balance is balance() resolve_initial_references (RootPOA); PortableServer:POA_var poa = PortableServer:POA:_narrow (poaobj); PortableServer:POAManager_var mgr = poa-the_POAManager(); Account_impl * account = new Account_impl; PortableServer:ObjectId_var oid = poa-activate_object (acco
21、unt); / Write reference to file mgr-activate (); orb-run(); poa-destroy (TRUE, TRUE); delete micocash; return 0;POA: Portable Object Adapter vvPOAPOA负责创建对象引用、激活对象以及分发请求负责创建对象引用、激活对象以及分发请求vvPOAPOA负责从负责从CORBACORBA对象到对象到servantservant之间的对应之间的对应 CORBACORBA对象与对象与servantservant对象的生命周期相互分开对象的生命周期相互分开vvPOAP
22、OA对于对于CORBACORBA服务器在性能、资源利用、可伸缩性等方服务器在性能、资源利用、可伸缩性等方面具有重要的意义面具有重要的意义vvPOAPOA策略,控制:策略,控制: 对象生命周期:永久对象、暂态对象对象生命周期:永久对象、暂态对象 对象标识符:在对象标识符:在POAPOA范围内唯一范围内唯一 POA Active Object MapPOA Active Object Map:从从ObjectIDObjectID到到servantservant的映射的映射 请求处理策略:请求处理策略:servant managerservant manager 线程模型线程模型 POA: Port
23、able Object Adapter(续续) vvPOAPOA的编程的编程 所有的工作都从所有的工作都从RootPOARootPOA开始开始 所有的所有的POAPOA构成一个树状层次结构构成一个树状层次结构 利用利用RootPOARootPOA的的create_POAcreate_POA创建新的创建新的POAPOA 在创建在创建POAPOA时指定策略,时指定策略,CORBA:CORBA:PolicyListPolicyListvvPOAPOA提供的功能提供的功能 创建对象创建对象 注册注册servantservant,激活对象激活对象 提供提供ObjectIDObjectID、ObjectR
24、eferenceObjectReference之间的转换之间的转换vvservant managerservant manager编程编程vvPOA managerPOA manager:控制来自客户的请求控制来自客户的请求 多个多个POAPOA可以共享同一个可以共享同一个POA managerPOA managervvORBORB事件处理事件处理服务器端服务器端C+ mapping(续四续四)vv利用利用idlidl生成的框架类编写生成的框架类编写servantservant类类vv编写编写mainmain函数函数 从从ORBORB初始化开始初始化开始 考虑考虑POAPOA的策略,简单的程序
25、可以使用默认的的策略,简单的程序可以使用默认的RootPOARootPOA 创建创建servantservant并注册并注册 处理对象引用处理对象引用 进入主循环进入主循环vv阻塞方式:阻塞方式:orb-run()orb-run()vv非阻塞方式:非阻塞方式:orb-work_pending()orb-work_pending()orb-perform_work()orb-perform_work()用用C+开发开发CORBA应用应用 vv基本的基本的C+C+知识,包括链表结构、智能指针的知识知识,包括链表结构、智能指针的知识vv针对当前使用的针对当前使用的ORBORB产品,熟悉对于基本数据类
26、型的产品,熟悉对于基本数据类型的支持,以及这些类型与当前平台上各数据类型的关系支持,以及这些类型与当前平台上各数据类型的关系vv理解理解CORBACORBA的的client/serverclient/server应用模型应用模型vv包含头文件包含头文件vv链接库文件链接库文件vv掌握掌握IDLIDL编译器编译器vv掌握掌握ORBORB接口接口vv如何传递对象引用如何传递对象引用ORB接口接口 vv初始:初始:CORBA:ORB_InitCORBA:ORB_Init,通过命令行传递参数通过命令行传递参数vv对象引用到字符串的转换操作对象引用到字符串的转换操作 对象引用:对象引用:CORBA:Ob
27、jectCORBA:Objectvv获得初始接口获得初始接口 resolve_initial_referenceresolve_initial_referenceDII:Dynamic Invocation Interfacevv客户程序可以不通过客户程序可以不通过IDLIDL编译器生成的编译器生成的stubstub而调而调用对象的方法,步骤:用对象的方法,步骤: 客户首先得到对象引用:客户首先得到对象引用:CORBA:Object_CORBA:Object_ptrptr 创建一个请求对象创建一个请求对象CORBA:Request_CORBA:Request_ptrptr 把调用参数放到链表中
28、:把调用参数放到链表中:CORBA:CORBA:NVListNVList_ _ptrptr,指明指明类型和数值,也指明返回值类型和数值,也指明返回值 调用调用CORBA:Request_CORBA:Request_ptrptr-Invoke-Invoke方法方法vv服务器并不知道客户程序是通过服务器并不知道客户程序是通过stubstub还是还是DIIDII调调用其方法的用其方法的vv客户程序在编译时刻可以没有客户程序在编译时刻可以没有idlidl类型知识类型知识vv比较:比较:COM AutomationCOM Automation中中IDispatchIDispatch接口的用法接口的用法用
29、用C+开发开发CORBA应用:客户应用:客户vv用用IDLIDL生成生成stubstub代码以及类型定义头文件代码以及类型定义头文件vv在客户的在客户的mainmain函数中,初始化函数中,初始化orborb,获得获得orborb对象对象vv获得对象引用,并调用获得对象引用,并调用_ _narrownarrow向下转换向下转换vv调用对象的方法调用对象的方法vv如果使用如果使用DIIDII,则需要用到请求对象,并处理参数则需要用到请求对象,并处理参数vv如果不用如果不用_ _varvar类型的话,释放类型的话,释放orborb和对象引用和对象引用DSI:Dynamic Skeleton Int
30、erfacevv服务器程序可以动态实现对象,而不利用服务器程序可以动态实现对象,而不利用IDLIDL编译器生成的编译器生成的skeletonskeleton代码代码vv服务器实现一个对象,如下所示服务器实现一个对象,如下所示class class GenericServantGenericServant : virtual public : virtual public PortableServerPortableServer: :DynamicImplementation DynamicImplementation virtual void invoke (CORBA: virtual vo
31、id invoke (CORBA:ServerRequestServerRequest_ _ptr reqptr req); ); virtual CORBA: virtual CORBA:RepositoryIdRepositoryId _primary_interface ( _primary_interface (constconst PortableServer PortableServer: :ObjectIdObjectId &, &, PortableServerPortableServer:POA_:POA_ptrptr); );vvmainmain函数的处理不变函数的处理不变
32、vv重点在于重点在于invokeinvoke函数,利用函数,利用CORBA:CORBA:ServerRequestServerRequest对象获得对象获得所有的类型信息所有的类型信息vv对于客户透明对于客户透明vv比较:比较:COM AutomationCOM Automation中中IDispatchIDispatch接口的实现接口的实现用用C+开发开发CORBA应用:服务器应用:服务器vv用用IDLIDL生成生成skeletonskeleton代码以及类型定义头文件代码以及类型定义头文件vv在客户的在客户的mainmain函数中,初始化函数中,初始化orborb,获得获得orborb对象
33、对象vv根据服务器应用的需要,处理根据服务器应用的需要,处理POAPOAvv创建创建servantservant对象对象vv如果使用如果使用DSIDSI,那么那么invokeinvoke方法是方法是servantservant对象的对象的关键关键vv如何把对象引用传递出去?字符串?名字服务?如何把对象引用传递出去?字符串?名字服务?vv调用调用orb-run()orb-run()或者或者orb-perform_work()orb-perform_work()CORBA IIOP和和IORvvGeneral Inter-ORB ProtocolGeneral Inter-ORB Protocol
34、:CORBACORBA定义了定义了GIOPGIOP作为其互作为其互用性框架结构,包括数据传输、数据表示、消息格式用性框架结构,包括数据传输、数据表示、消息格式vvInternet Inter-ORB ProtocolInternet Inter-ORB Protocol:IIOPIIOP是是GIOPGIOP的具体实现,建的具体实现,建立在立在TCP/IPTCP/IP基础上基础上vvIORIOR:Interoperable object referenceInteroperable object referenceRepositoryID Data for Protocol 1 Data for
35、 Protocol 2 Endpoint Info Object KeyObject IDIOR例子例子 Repo Id: IDL:GenericServer:1.0Repo Id: IDL:GenericServer:1.0IIOP ProfileIIOP Profile Version: 1.0 Version: 1.0 Address: inet:162.105.178.100:12122 Address: inet:162.105.178.100:12122 Location: corbaloc:162.105.73.196:12122/25607/991958392/%5f0 Loc
36、ation: corbaloc:162.105.73.196:12122/25607/991958392/%5f0 Key: 2f 32 35 36 30 37 2f 39 39 31 39 35 38 33 39 32 /25607/991958392 Key: 2f 32 35 36 30 37 2f 39 39 31 39 35 38 33 39 32 /25607/991958392 2f 5f 30 /_0 2f 5f 30 /_0Multiple Components ProfileMultiple Components Profile Components: Native Cod
37、esets: Components: Native Codesets: normal: ISO 8859-1:1987; Latin Alphabet No. 1 normal: ISO 8859-1:1987; Latin Alphabet No. 1 wide: ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16- wide: ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit formbit form Key: 00 . Key: 00 .CORBA
38、结构结构CORBA services:naming service vv建立起建立起“ “名称名称- -对象引用对象引用” ”的映射关系的映射关系vv在内部以层次结构的形式组织名字映射,类似于文件在内部以层次结构的形式组织名字映射,类似于文件系统的结构。系统的结构。vv所有的类型和接口定义位于所有的类型和接口定义位于CosNamingCosNaming域中域中vvNamingContextNamingContext接口负责所有有关命名服务相关的功能,接口负责所有有关命名服务相关的功能,例如:例如: 创建新的创建新的contextcontext、删除删除contextcontext bindbi
39、nd操作、操作、unbindunbind操作操作 resolveresolve操作操作vv怎样获得初始怎样获得初始namingcontextnamingcontext? 通过通过orb-resolve_initial_referenceorb-resolve_initial_referencevvORBORB厂商应该提供命名服务工具厂商应该提供命名服务工具naming service示例示例 CORBA:Object_CORBA:Object_var nsobjvar nsobj = = orb-resolve_initial_referencesorb-resolve_initial_ref
40、erences ( (NameServiceNameService);); CosNamingCosNaming: :NamingContextNamingContext_ _var ncvar nc = = CosNamingCosNaming: :NamingContextNamingContext:_narrow (:_narrow (nsobjnsobj); ); CosNamingCosNaming:Name name:Name name; ; name.length (1); name.length (1); name0.id = CORBA:string_dup ( name0.
41、id = CORBA:string_dup (myAccountmyAccount);); name0.kind = CORBA:string_dup (); name0.kind = CORBA:string_dup ();/ / 服务器方服务器方 Account_Account_ptrptr acc = new Account_ acc = new Account_implimpl (); (); ncnc-bind (name, acc);-bind (name, acc);/ / 客户方客户方 CORBA:Object_CORBA:Object_var objvar obj; ; ob
42、jobj = = ncnc-resolve (name);-resolve (name); Account_ Account_varvar client = Account:_narrow( client = Account:_narrow( objobj ); );CORBA services:其他服务其他服务vvEvent serviceEvent service 提供松耦合事件模型的机制提供松耦合事件模型的机制vvTrade ServiceTrade Service 提供了更加灵活的对象查找服务提供了更加灵活的对象查找服务vvTime ServiceTime Service 提供了与时间
43、有关的服务,统一了时间的表达方式提供了与时间有关的服务,统一了时间的表达方式vvConcurrency serviceConcurrency servicevvSecurity ServiceSecurity ServicevvTransaction ServiceTransaction ServicevvORB产品产品vv考察考察ORBORB:支持平台、支持语言、性能支持平台、支持语言、性能vv商业商业ORBORB OrbixOrbix,IONAIONA公司,完全支持公司,完全支持CORBA 2.3CORBA 2.3规范规范 VisibrokerVisibroker,InpriseInpri
44、se公司,公司,4.04.0版完全支持版完全支持2.32.3规范规范Netscape communicatorNetscape communicator浏览器嵌入浏览器嵌入VisibrokerVisibrokervv自由自由ORBORB ORBitORBit,遵循CORBA 2.2规范,支持C语言,性能较高 micomico,GNUGNU,OpenSourceOpenSource TAOTAO,美国华盛顿大学分布式对象计算研究小组 omniORBomniORB,AT&T剑桥实验室CORBA与与COM的比较的比较vv标准的层次不同标准的层次不同 CORBACORBA与与JavaJava结合的优势结合的优势vvCORBACORBA跨平台优势跨平台优势vvCOMCOM在在WindowsWindows平台上的优势平台上的优势vvCOMCOM的效率有优势的效率有优势vv跨语言的策略不同跨语言的策略不同vvCOMCOM组件丰富、组件丰富、CORBACORBA开发简单开发简单 CORBACORBA不适合开发不适合开发UIUI组件组件vvCORBACORBA与与COMCOM互补策略互补策略