opencascade 第1章 OCC体系结构和基本概念 原创
第1章 OCC体系结构和基本概念
前言
OCC是面向对象方法设计的一个CAD基础平台(软件)。为了能从整体上把握OCC的组织情况,也为了方便后续章节的讨论,本章将介绍OCC体系结构和几个基本概念。
1.1 OCC体系结构
1.1.1面向对象方法和面向对象的软件工程
在介绍OCC体系结构之前,先介绍面向对象方法的概念和什么叫面向对象的软件工程。
在面向对象的方法出现以前,程序员都采用面向过程的程序设计方法,其中典型的是结构化程序设计。这种设计的思路是:自顶向下、逐步求精。其程序结构是按功能划分为若干个基本模块,这些模块形成一个树状结构。各模块间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成。其模块化实现的具体方法是使用子程序。结构化程序设计由于采用了模块分解与功能抽象以及自顶向下、分而治之的方法,从而有效的将一个复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。这种设计方法的致命缺点是:程序的可重用性差。因为它把数据和处理数据的过程分离为相互独立的实体,当数据结构改变时,所有相关的处理过程都要进行相应的修改。
而面向对象的方法将数据及对数据的操作放在一起,作为一个相互依存、不可分离的整体——对象。对同类型对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。这样,程序模块间的关系更为简单,程序模块的独立性、数据的安全性就有了良好的保障,实现了“高内聚”“低耦合”.另外,继承与多态性可以大大提高程序的可重用性,使得软件的开发和维护都更为方便。
面向对象的软件工程是面向对象方法在软件工程领域的全面应用。它包括面向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。
1.1.2OCC的体系结构
整个OCC就是用面向对象方法设计出来的一个对象库。之所以用面向对象方法而不是面向过程方法,是因为用面向对象方法有三个好处。
第一,由面向对象方法抽象的系统结构能映射到数据库结构中,很容易实现程序与数据结构的封装。
第二,面向对象方法从所处理的数据入手,以数据为中心来描述系统,数据相对于功能而言,具有更强的稳定性,这样设计出的系统模型往往能较好地映射问题域模型。
第三,对象、类、继承性、多态性的引入使用,令面向对象的设计方法能更好地生产可重用的软件构件和解决软件的复杂性问题。
不过,面向对象的设计方法要求开发人员必须花很大精力去分析对象是什么,每个对象应该承担什么责任,所有这些对象怎样很好地合作以完成预定的目标。这样做换来的好处是:提高了目标系统的可重用性,减少了生命周期后续阶段的工作量和可能犯的错误,提高了软件的可维护性。
用面向对象方法和软件工程思想分析,整个OCC由五个模块组成,分别是基础类模块、建模数据模块、建模算法模块、可视化模块、数据交换模块和应用程序模块。其中,建模数据模块主要提供二维和三维几何模型的数据结构,也称数据结构模块。
一个模块主要由一个或几个工具箱构成。当然它也可以包含一些执行体和资源体等。就结构上看,一个工具箱就是一个共享库(如.so或.dll类型的文件)。每个工具箱由一个或几个包组成。而每个包则由许多类组成,例如,
一个几何包包含点类、线类和圆类等。在同一个包中,不能含有相同名字的两个类。使用类的时候,类名要以包名作前缀,如Geom_Circle。
图2.1简要说明了包的内容。
1.2基本概念
1.2.1类和泛化
1、类
OCC是一个面向对象的软件,与所有面向对象的软件一样,其最基本的软件成分是类。一个类就是一种数据类型的实现。类有自己的行为(由它的函数提供的服务)和结构(类的数据结构——用来存储其数据)。
OCC中所有类按其实现方式可以分三种:普通类、推迟类和通用类。普通类含有实例方法,可以被直接实例化。而推迟类则不能被实例化。推迟类的作用在于使一层类共同拥有一种给定的行为,而这些行为的发生取决于普通类(推迟类的派生类)的实现。通过推迟类的创建,可以保证所有派生自同一推迟类的普通类拥有相同的继承行为。在C++中,与推迟类等同的是抽象类。
至于通用类,它提供了一套处理其他数据类型的功能行为。通用类的实例化需要为它的参数指定类型。通用类的作用与C++中模板类的作用一样。
2、泛化
这里所谓的泛化,主要是通过通用类的实现来获得的。
通用类分两步实现。首先,对一个通用类进行声明以建立模型。在CDL(CASCADE定义语言)中,通用类被声明为对不确定类型数据项的操作。这里的数据项就是通用类中的形参。对通用类的形参进行限制,就可以使形参类型成为普通类的子类。要注意的是:声明一个通用类并没有创建一个新的类类型,而只是定义了一种适用于几个普通类的通用形式。然后,赋予通用类型信息对该通用类进行实例化。通用类被实例化时,它的形参类型由实参类型(基本类型或基本类)替代。实例化结束后,就创建出一个新的类。新类可以由用户在实例化声明中任意命名。按惯例,通用类的实例名通常由通用类名和实参类型名组成。至于通用类的名字,只需在其本身名字前添加一个前缀(该通用类所在包的名字)。
例2.1:
class Array1OfReal instantiates Array1 from TCollection (Real);
这个声明位于TColstd包的一个CDL文件中。它定义了一个新的类TColstd_Array1OfReal。该类是通用类 TCollection_Array1的一个实例,并且参数类型指定为实型。
从具有相同形参类型的相同通用类中,可以实例化出不止一个类。这些实例化出来的类通过各自的实现来识别。其实在C++中,它们已经不属于同一类了,另外,我们不能从通用类中派生类。
在由通用类获得的泛化中,我们经常发现许多类由一个共同的通用类型联系着。这种现象发生在一种基本结构供给迭代器的时候。在这种情况下,有必要弄清一件事,那就是由相关通用类构成的团体的确用于同一对象类型的实例化。为了使这个实例化过程成为一整体,可以将一些通用类声明为内嵌类。这样的通用类就叫内嵌通用类。
一旦主通用类被实例化,它的内嵌类也将被实例化。内嵌类的实例名由内嵌类名字和主通用类名字组成,通过“Of”连接。
例2.2:
class MapOfReal instantiates Map from TCollection (Real,MapRealHasher);
这个声明位于TColstd中。它不仅定义了TColstd_MapOfReal类,也定义了TColstd_MapIteratorOfMapOfReal类(该类是通用类TCollection_Map 的内嵌类MapIterator 的一个实例)。内嵌类的实例独立于主类的实例,而决非绑定于它。作为内嵌类,即使它们本身不是通用类,但是内嵌于通用类,它们也是通用的。
1.2.2数据类型的分类
数据类型是作为类被实现的。类不仅定义了它的数据结构和基于它的实例的方法,也声明了该实例的处理方式。
依据处理方式(见图2.2)的不同,OCC中所有数据类型可分为两大类:通过句柄(或引用)处理的数据类型和通过值处理的数据类型。一个通过值处理的类型变量包含自己的实例;而一个通过句柄处理的类型变量包含一个实例的引用。
通过值处理的类型首先有基本类型,如布尔类型、字符型、整型、实型等。通过句柄处理的类型变量,如果它不指向任何对象,那我们就说它是空的。要引用一个对象,我们就得用它的一个构造函数实例化该对象,如例2.3。
例2.3:
Handle(myClass) m = new myClass;
在OCC 中,句柄是一些特殊类,它们以引用的方式对动态存储对象进行安全处理。句柄提供了一种引用计算机制,通过这种机制,当对象不被引用时,可以自动析构对象。
1.2.3持久化和数据模式
数据模式是应用程序用来存储数据的一种结构,由一些持久类构成。
一个对象若可以被永久存储,则是持久的。持久对象可以被它的创建程序或其它程序在以后的时间里再次使用。
要想使一个对象在CDL中是持久的,必须声明它的类型继承自Standard_Persistent类或其派生类。所有继承自Standard_Persistent类的类都是通过引用处理的。
对于由Standard_Storable类派生出的所有类,它们的实例(对象)是不能被
单独存储的,但是可以作为持久对象的区域被存储,所有继承自Standard_Storable类的类,其对象都是通过值处理的。
1.3 本章小结
本章用面向对象方法和软件工程思想从整体上分析了OCC的体系结构。整个OCC包含五个模块;模块中包含工具箱;工具箱中包含包;包中包含类:类是OCC软件的最基本要素。
本章还介绍了OCC的几个基本概念:类、泛化、数据类型的分类、持久化和数据模式。与C++类的命名不同,OCC有自己的命名方法。OCC 中类分为普通类、推迟类和通用类三种,分别对应C++中的具体类、抽象类和模板类。OCC的数据可以分为句柄处理类型和值处理类型两种。OCC的持久化和数据模式与一般软件的原理相同,不同的是:为了使对象持久化,需要声明该对象是由Standard_Persistent类或其派生类派生的。