Visualization Toolkit官方开发文档翻译(3)–第二章面向对象设计

面向对象的系统在计算机行业中越来越普遍是有充分理由的。与传统的过程系统相比,面向对象的系统更模块化、更易于维护和更易于描述。由于Visualization Toolkit是使用面向对象的设计来设计和实现的,所以我们用这一章来总结面向对象设计和实现的概念和实践。

2.1 简介

今天的软件系统试图解决复杂的现实问题。严格的软件设计和实施方法可以减轻这种复杂性的负担。如果没有这样的方法,软件开发人员会发现很难满足系统的规范。此外,随着规范的变化和增长,没有坚实的底层架构和设计的软件系统将难以适应这些不断扩展的需求。

我们的可视化系统是需要在设计时考虑到可扩展性的复杂软件的一个很好的例子。数据可视化是一个快速发展的领域,每年都会引入可视化技术。任何希望融入未来创新的系统都必须具有支持添加新材料而不会对现有系统产生重大影响的基础设计。

面向对象设计是一种软件工程方法,可以轻松处理复杂性,并为以后的更改和添加提供框架。面向对象的设计过程试图将复杂的任务划分为称为对象的小而简单的部分。对象是模拟系统的物理或抽象部分的计算机抽象。面向对象的设计方法提供了识别系统中存在的抽象并对对象的行为进行建模的机制。

2.2 优秀软件设计的目标

软件设计的质量很难衡量,但一些定性方面可以指导我们。一个好的软件设计应该是健壮的、可理解的、可扩展的、模块化的、可维护的和可重用的。

一个强大的系统可以优雅地处理异常情况并始终如一地运行。稳健性使软件开发人员相信系统的底层组件将按预期运行,即使系统在与原始实现者预期不同的环境下使用时也是如此。

原始实施者以外的其他人可以使用可理解的系统。该系统的使用应该看起来合乎逻辑和明智。系统组件的名称应源自问题域。

可扩展系统在接受新任务的同时仍然执行它们最初打算执行的任务。一个系统应该在不破坏现有软件的情况下接受新形式的数据和新算法。向系统添加新原语不应导致系统的大部分被修改。经验表明,系统中修改的现有代码越多,引入错误的可能性就越大。

模块化软件系统最大限度地减少了系统组件之间存在的关系数量。紧密耦合的系统组件应该在逻辑上组合在一起,并遵守通用的命名约定和协议。

在系统设计过程中,软件维护经常被忽略。然而,系统的总成本包括维护和原始开发。如果问题很容易被隔离并且一个问题的修复不会在系统的不相关部分中引入问题,则软件系统是可维护的。

最后,软件开发的经济学要求我们尽可能多地利用我们过去的工作。在理想的世界中,在现有系统中实施新技术应该是一项简单的任务。这在软件系统中很少出现。创建可重用的软件组件可以减少重复工作并促进系统内的一致接口。然而,正如我们在本书中看到的那样,创建可重用的软件通常需要付出额外的努力。个人对生产力的短期看法与软件开发组织对生产力的长期看法相冲突。

2.3 面向对象的概念

对象是面向对象系统中的主导概念。对象是封装系统内实体的属性和行为的抽象。每个对象都有一个标识,将它与系统中的其他对象区分开来。通常,一个对象的可区分方面是显而易见的。例如,颜色、屏幕上的位置、大小或内容的差异将一个窗口与计算机桌面上的另一个窗口区分开来。但是,外表可能具有欺骗性,即使两个具有相同特征的物体也可能具有不同的身份。两辆汽车可能具有相同的制造商、型号、选项和颜色,但仍然是两辆不同的汽车。现实世界通过车辆识别号区分两辆车。同样,处理多个实体的编程系统需要一种身份机制。指向已分配内存的指针或系统管理的符号表中的变量名通常用于区分系统中的对象。在数据库系统中,一组标识符键(称为n -tuple) 标识系统中的实体。

但是,面向对象系统与传统的过程编程系统有何不同?主要区别在于两种方法处理数据抽象的方式。传统系统将抽象限制为数据类型,而面向对象系统为数据和可应用于数据的操作创建抽象。事实上,面向对象的系统将数据和操作保存在一个称为对象的编程结构中。数据和操作一起构成了对象的属性. 当对对象应用操作时,编程语言的动态绑定机制会执行适合该对象的过程。在面向过程的系统中情况并非如此。程序员必须提供逻辑来决定调用哪个过程。处理多种类型的系统通常充斥着 case 语句,以选择适当的操作过程。随着新类型添加到这些系统中,必须扩展基于数据类型分派操作的代码以处理新类型。例如,在显示不同类型原语的程序中,以下伪代码显示了面向过程的系统与面向对象的系统有何不同。

面向过程(在 C 中):

Primitive *aPrim;
...
DrawPrimitive (aPrim)
...
procedure DrawPrimitive (aPrim)
  {
  if (aPrim->type == TRIANGLE) then DrawTriangle (aPrim)
  else if (aPrim->type == SQUARE) then DrawSquare (aPrim)
  else if (aPrim->type == CIRCLE) then DrawCircle (aPrim)
  ...
  }

面向对象(在 C++ 中):

...
aPrim->Draw ();
...

在这个项目的后期,有人可能想要添加一个新的基元,比如说一个二次元。分配给如此艰巨任务的人必须在现有系统中搜索第一个示例中出现的所有 if 语句,并为新的二次类型添加测试。当然,一个好的程序员会将代码隔离在一个位置,就像我们在这里所做的那样,所以任务更容易。尽管如此,该程序员必须首先意识到原始程序员足够熟练地将绘图代码模块化,然后找到代码(不一定知道过程名称)并修改代码。更复杂的是,由多个程序员构建的系统无疑会处于配置管理系统之下,需要一个签出、编辑和签入周期。

面向对象的程序员有一个更容易的任务。查阅定义图元对象属性的设计文档,该程序员将绘制操作添加到二次对象。新原语可供系统使用,无需更改任何现有代码!当然,这是一个过于简单的例子。但是想想你过去编写的程序,并记住添加新数据类型是多么困难。您的更改是否与您添加的新代码隔离?您是否必须编辑您未编写并且可能不理解的代码?当您阅读我们的数据可视化库的面向对象实现时,请记住这个示例。

在更详细地描述面向对象的设计和编程之前,我们提供一个观察和预测。在我们使用面向对象方法设计和实现软件的几年中,我们观察到该技术的新手会说:“但这就是我已经编写程序的方式。我的系统是模块化的;它们很健壮;我可以很容易地添加到它们中。” 如果您在阅读本书后仍然有这种感觉,请不要指责面向对象的方法。相反,我们作为作者失败了。然而,这样的负面反应是不可能的。根据我们的经验,用户会在短时间内适应这种方法。尤其是当它们通过现有的、设计良好的面向对象系统引入对象时。你会达到“啊哈”的阶段,

2.4 面向对象的术语

与任何软件工程设计方法一样,面向对象设计也有自己的术语。不幸的是,并不是每个人都同意那是什么。我们采用了来自 Rumbaugh [Rumbaugh91]的大部分术语,并且由于Visualization Toolkit是用 C++ 编写的,因此来自 Stroustrup [Stroustrup84]。在大多数情况下,Rumbaugh 的术语独立于编程语言,而 Stroustrup 则特定于 C++ 中的实现。不过,从设计到编程的过渡将是无痛的,并且这两个术语之间的映射非常明显。在我们认为可能存在混淆的地方,我们将指出对应关系。

什么是对象?

对象是对系统中实体的状态和行为进行建模的抽象。抽象是一种心理过程,它为特定目的提取情况的基本方面。实体是系统中具有身份的事物。椅子、飞机和照相机是与现实世界中的物理实体相对应的对象。二叉树、符号表和有序集合是仅存在于计算机科学领域的对象。

图 2-1是我们将系统组件的状态和行为映射到对象时发生的抽象示例。在这里,对象是一种特殊类型的树:针橡树。在这个应用程序中,我们希望模拟不同类型树木在一个季节中的生长。为了我们的目的,我们决定重要的状态变量是树的年龄、树干直径、高度和习性(即生长形式)。为了捕捉针栎的行为,我们有方法来模拟与春季、夏季、秋季和冬季相对应的生长和季节效应。还有一些方法(未显示)用于设置和获取当前状态变量。

图2-1
图 2-1。将现实世界的对象映射到对象抽象中。现实世界的对象是各种类型的树。其中一个对象(一棵橡树)被映射到我们称为 PinOak 的计算机对象中。

我们将对象的状态称为其属性(也称为实例变量),并通过可应用于它的操作来定义其行为。属性具有名称、数据类型和数据值。属性的数据类型可以是编程语言中的原始类型(例如 C++ 中的 char 或 float),也可以是其他对象。例如,我们可视化系统中的vtkTransform对象有一个类型为vtkMatrix4x4的属性,即另一个对象。vtkMatrix4x4又具有属性,这些属性是在 C++ 中声明为浮点值的原始值数组。

操作是可以应用于对象的函数或转换。操作定义对象的行为。特定对象的操作在我们称为方法的过程中实现。

对象的属性和操作共同构成了它的属性。二维折线图可以具有包括xy轴、图例和一组连接的点的属性。该图表具有在窗口中绘制图表的方法。它还具有让用户指定要绘制的轴、要绘制的数据和要使用的图例的方法。

可以使用分类过程对具有相同属性的对象进行分组。对象类,通常简称为类,指定类中所有对象所具有的属性。该类仅指定属性的名称,而不是它们的具体值。不同的类可以(并且通常确实)具有其他类中存在的名称的属性。我们可视化系统中的许多类都有一个名为 Position 的属性。尽管我们的可视化系统中的相机和演员都有这个属性,但它们的效果是不同的,因为它们是不同的类。属性名称由给定类中的所有对象共享,但为每个对象的属性值分配单独的存储空间。

当同名操作应用于不同类的对象时,我们称操作多态。例如,我们的可视化系统有一个名为 Render() 的操作,可以应用于许多不同的对象。特定类的操作的实现称为方法。vtkMatrix4x4对象的打印操作在其打印方法中实现。也就是说,存在知道如何打印vtkMatrix4x4类对象的代码而不是其他类的对象。对象知道使用哪种方法,因为它们保存在每个对象的数据结构中。在大多数系统中,方法的代码由同一类中的所有对象共享。一些编程语言,包括 C++,通过将操作名称与其参数类型相结合来定义方法。此过程称为重载操作,是一种强大的技术,允许将相同的名称用于逻辑上相似的操作。例如,下面的类定义定义了三种计算数字平方的方法。即使这些方法具有相同的操作名称,它们也是唯一的,因为 C++ 使用操作名称和操作参数类型。

class math
{
  float square(float x);
  int square(int x);
  double square(double x);
}

为了某种目的使用一个类的成员,我们创建一个类的实例(实例化的过程)。实例创建建立实例的身份,包括指定其初始状态。实例的类在创建过程中用作实例的模板,定义其每个属性和操作的名称。创建建立了该实例与同一类的其他实例之间的异同。相似之处在于其属性的名称和类型以及实现其操作的方法。不同之处在于属性的特定值。如何创建一个类的实例的细节因编程语言而异。在 C++ 中,程序使用声明形式创建实例,例如

vtkActor aBall;

它从程序堆栈创建一个对象,或者通过应用新操作

vtkActor *aBall = new vtkActor;

它从程序堆创建对象。

遗产

继承是一种编程机制,当新类与当前现有类有细微差别时,它可以简化向系统添加新类的过程。继承的概念是根据大多数系统可以使用分层分类系统来指定的观察而采用的。分类系统的一个很好的例子是地球上的生命门。

之前我们创建了一个对应于针橡树的对象。使用继承可以更彻底地描述树的属性(图 2-2)。这里显示的分类基于 Margulis 和 Schwartz [Margulis88]的五国系统。在这个系统中,生物群被归类为原核生物(细菌)、原核生物(藻类、原生动物和粘菌)、真菌(蘑菇、霉菌、地衣)、植物(苔藓、蕨类植物、球果和开花植物)和动物界(有和没有骨干的动物)。在这个层次之下,我们有分类、类、目、科、属和种。该图显示了针栎的王国、科、类、属和种。

将对象组织成继承层次结构提供了许多好处。一般分类的属性也是其子分类的属性。例如,我们知道栎属的所有物种都会形成橡子。从软件的角度来看,这意味着超类的任何实例变量和方法都会被其自动继承。这允许我们通过修改它们的超类来同时更改多个对象。此外,如果我们希望在层次结构中添加一个新类(比如一棵红橡树),我们可以在不复制现有功能的情况下这样做。我们只需通过添加新的实例变量或重载现有方法来将新类与其他类区分开来。

图2-2图 2-2。针橡树的继承层次结构。

快速添加与现有类略有不同的新类的能力促进了系统的可扩展性。继承可以使用称为specialization的过程自上而下派生,也可以自下而上创建,在称为generalization的过程中组合相似的类。继承的使用意味着一个类层次结构,其中一个或多个类是一个或多个子类的超类。子类继承其超类的操作和属性。在 C++ 中,子类称为派生类,超类称为基类类。子类可以添加额外的操作和属性来修改它从其超类继承的属性。通过这种继承,一个对象可以展示其超类的行为以及它希望的任何其他行为。它还可以限制或覆盖由其超类实现的操作。

仅作为其子类的超类而存在的类称为抽象类。通常禁止创建抽象类的实例。抽象类对于收集所有子类将使用的属性和方法很有用。他们还可以为其子类定义行为协议。这是继承的强大用途,将出现在我们的可视化系统的设计中。抽象类可以强制执行复杂的序列、控制协议并确保统一的行为。它们从各个子类中移除了复杂协议的责任,并将协议隔离在超类中。

一个简单的绘图包示例说明了抽象类的强大功能。考虑一个允许各种二维绘图的数据表示应用程序。此应用程序必须支持折线图和水平和垂直条形图。设计过程识别所有绘图共有的属性,包括标题、轴和图例。然后我们创建一个名为 TwoDPlot 的抽象类来包含这些公共属性。常见的行为也可以在 TwoDPlot 的 plot 方法中被捕获:

Method Plot
{
  Draw the border
  Scale the data
  Draw the axes
  Draw the data
  Draw the title
  Draw the legend
}

抽象类可能会也可能不会为每个操作提供默认行为。在此示例中,可能会提供边框和标题绘制的默认行为。然后 TwoDPlot 的子类将为其他方法定义自己的函数。协议规范明确说明了 TwoDPlot 的子类应该响应哪些方法。在上面的示例中,子类将需要定义自己的方法来绘制轴、数据和图例。一些子类可能使用 TwoDPlot 的方法来绘制边框,其他子类可能需要他们自己的此方法版本。TwoDPlot 中定义的抽象接口使得添加新的 2D 绘图类变得更加容易,并且生成的子类往往更加统一和一致。

另一种机制,委托,对于隔离和重用行为很有用。使用委托,对象将操作应用于其属性之一,即对象。例如,在Visualization Toolkit中,vtkTransform对象将其 Identity() 操作委托给其vtkMatrix4x4属性。这个vtkMatrix4x4实例然后执行操作。还有很多有用的面向对象概念,但目前我们有足够的信息来描述如何使用对象来设计系统。

2.5 面向对象的建模与设计

任何大型软件系统的设计都是一项艰巨的任务,系统设计的第一步通常是最具挑战性的。无论选择何种设计技术,都必须对系统的应用领域有透彻的了解。如果没有对底层硬件控制系统的详细了解,很难看出如何设计电传操纵飞机控制系统。当然,所有的飞行系统软件都不是由航空工程师设计的,因此必须存在某种形式的系统规范。规范中的信息深度因应用而异。

面向对象的系统设计从一个建模步骤开始,该步骤从问题陈述或软件需求规范中提取对象及其与其他对象的关系。首先,设计者必须完全理解要解决的问题。这通常需要对问题域有深入的了解或访问正在解决的问题的详细说明。然后,必须在系统内识别主要抽象。在这种高级设计中,抽象将成为第一组对象。例如,跟踪投资组合的系统将需要股票、债券和共同基金等对象。在计算机动画系统中,我们可能需要演员、摄像机和灯光。一个医学计算机断层扫描系统将有一个工作台、X 射线源、探测器和机架。我们的可视化系统将包含模型、等值面、流线和剖切面。在此建模步骤中,我们在问题域中搜索对象、属性和关系。稍后,在多次通过设计时,模型将被扩展。

无论我们是设计船舶、房屋、电子系统还是软件,建模都是大多数设计过程中的一个步骤。每个学科都遵循一种方法,该方法使用专门创建的技术来使设计过程高效且有价值。这些技术是所谓的“交易工具”。电气工程师使用原理图和逻辑图,建筑师使用图纸和模型,造船厂使用比例模型。同样,软件设计人员需要可以帮助创建系统模型的工具。软件工具应该有足够的表达能力来帮助软件设计师根据规范评估设计,并帮助将该设计传达给软件团队中的其他人。

我们使用由 Jim Rumbaugh 和他的同事[Rumbaugh91]在 GE 开发的对象建模技术 (OMT) 。OMT 使用三个模型来指定面向对象的设计:对象模型、动态模型和功能模型。每个模型都描述了系统的不同方面,并且每个模型都有相应的图表技术,可以帮助我们分析、设计和实施软件系统。

对象模型

对象模型识别系统中的每个对象、它的属性以及它与系统中其他对象的关系。对于大多数软件系统,对象模型支配着设计。OMT 图形技术使用矩形来描述对象类,并使用各种连接器来描述继承和其他对象-对象关系。对象类表示为实心矩形。实例表示为虚线矩形。类或实例的名称占据矩形的顶部。一行将类名与包含属性的下一部分分开;第三部分描述了这些方法。对象之间的关系显示为连接两个相关对象的线段。在 OMT 中,关系称为关联,它们可以有多种基数:一对一、一对多、和多对多。表示其他对象容器的特殊关联称为聚合。关联可以用角色标记。(角色是关联的名称,用于进一步描述关联的性质。)OMT 表示具有三角形的继承,超类连接到顶点,子类连接到三角形的底部。图 2-3显示了虚拟现实系统中定位器设备的对象模型。

类层次结构中的第一个对象是定位器。这个抽象类为所有定位器指定了公共属性和方法。定位器的子类是 locator2D 和 locator3D 在这个对象模型的当前版本中,定位器只有一个属性,一个设备和两个方法,open() 和 close() locator 的两个子类 locator2D 和 locator3D 也是抽象类,包含根据空间维度将它们区分开来的属性和方法。例如,locator3D 有一个x,y,z位置,而 locator2D 有一个x,y位置。两个定位器都有一个 locate() 方法来更新当前位置。在 3D 定位器类中,locate() 也会更新方向。locator3D 的子类包括来自三个不同制造商的硬件:flock、pixsys 和 logitek,以及一个铰接定位器抽象类​​。硬件的三个对象类包含特定于每个设备的方法。每种方法都知道如何转换设备返回的硬件特定代码。他们知道要被视为 locator3D 子类,他们必须实现将提供x、y、z的位置和方向操作坐标和三个角旋转可以组成一个变换矩阵。对象模型还向我们展示了铰接式定位器具有角度和连杆。两个特定的铰接式定位器是沉浸式和幻象式。以这种方式绘制的对象模型可作为设计和讨论的起点。它揭示了常用的方法和属性以及每个类的区别特征。

稍后,在实现过程中,我们会将这些对象模型转换为软件对象。我们选择用于实现的特定计算机语言将决定转换的细节。

图2-3图 2-3。定位器设备的对象模型。

动态模型

对象模型描述系统的静态部分,而动态模型详细描述系统的事件序列和时间依赖性。OMT 使用状态图对系统动态进行建模。动态模型经常用于设计控制系统和用户界面。我们的可视化系统具有有限的序列和控制方面,因此我们不会详述状态图。但是,如果我们为数字手表设计一个用户友好的界面,状态图图2-4会有用的。

图 2-4图 2-4。手表的状态图。

图中的椭圆表示状态;箭头表示从一种状态到另一种状态的过渡;箭头上的标签显示了导致状态转换的事件。此示例显示了三种显示状态和多种设置状态。事件 b1 表示按下按钮一。这款手表有三个按钮。该图显示了当按下三个按钮中的任何一个时在每种状态下会发生什么。该图清楚地表明,b1 用于在时间、日期和闹钟的显示模式之间移动。B2 从显示模式更改为设置模式或选择要在给定模式中更改的字段。B3 将所选字段增加一个单位。状态图还显示了按下非法按钮时会发生什么。如果手表正在显示时间并且按下按钮 3,则没有任何反应。如果在手表显示闹铃时按下按钮 3,

功能模型

功能模型显示数据如何流经系统以及流程和算法如何转换数据。它还显示了进程之间的功能依赖关系。暴露这些关系将影响对象模型中的关联。数据流图 (DFD) 的主要组件是数据源、数据接收器和流程。数据源和接收器用矩形表示。省略号表示过程。数据存储显示在两条水平线内。DFD 可用于描述系统中的整体流程。它们还可用于描述将一种数据表示转换为另一种表示的任何过程。在功能建模期间在 DFD 中识别的过程可能会作为对象模型中的操作或对象出现。

图2-5显示了 3D 医学成像系统的数据流图。该图显示了计算机断层扫描 (CT) 或磁共振成像 (MRI) 扫描仪上的数据采集。扫描仪提供的一系列横截面切片首先由图像处理过滤器处理,以增强灰度切片中的特征。分段过程识别组织并为切片中存在的各种组织生成标签。这些标记的切片然后通过表面提取过程以创建位于每个组织表面的三角形。渲染过程将几何图形转换为图像。或者,写入过程将三角形存储在文件中。稍后,可以读取三角形并将其渲染为图像。我们将决定是否使流程对象或操作推迟到以后。

图2-5图 2-5。数据流图。

2.6 面向对象的编程语言

计算机编程语言的选择是一个宗教问题。每种计算机语言都有其传播者和追随者。我们在面向对象语言方面的大部分经验是使用 C 和 C++。C 本身没有面向对象的工具,但是面向对象的方法论和严格的编码准则允许开发面向对象的代码。我们为Visualization Toolkit选择了 C++,因为它内置了对类概念、方法与对象的动态绑定以及继承的支持。C++ 也广泛用于许多 UNIX 平台和个人计算机。

Simula [Birtwistle79]通常被认为是第一个面向对象的语言,但 Smalltalk [Goldberg83]可能是最知名的语言。Smalltalk 是在七八十年代在施乐帕洛阿尔托研究中心 (PARC) 开发的。早在它出现之前,Smalltalk 不仅提供了一种语言,而且还提供了一个使用对象构建的操作系统和编程环境。当您使用 Smalltalk 时,您会生活和呼吸对象。对于面向对象的纯粹主义者来说,没有替代品。Smalltalk 的衍生产品包括窗口系统、工作站和桌面范例。Apple Computer 和 Microsoft 都承认 Smalltalk 和 Xerox PARC 对 Macintosh 和 Windows 的影响。Smalltalk 的构想可能早了 10 年,无法被广泛的商业接受。在 Smalltalk 的婴儿期和青春期,软件的复杂性远低于今天的系统。FORTRAN 服务于科学和工程界,COBOL 是商业应用程序的选择,计算机科学界接受了 C。抽象的使用仅限于数学家和其他抽象思想家。编程被认为是一种艺术形式,程序员专注于算法的巧妙实现。每项新任务通常都需要一个新程序。技术程序员确实使用数值库来进行常见的数学运算,但任何更高级别的常见抽象概念都相对较少。

2.7 面向对象的可视化

不要低估设计系统所需的投资。尽管面向对象技术具有产生良好软件设计的巨大潜力,但这些技术并不能保证良好的设计。我们在本文中介绍的可视化系统源于动画[Lorensen89]和可视化系统[Schroeder92]我们开发了 10 年的时间。最初的设计确定了 25 个工业应用计算机动画课程,花了 4 名软件专业人员 10 个月(几乎 3.5 人年)完成。在这个设计阶段,开发人员生成了零(!)行代码。随后的实施花费了一个月的时间,也就是 10% 的工作量。即使在其他 20 位软件开发人员向系统中添加了 500 多个类之后,该系统仍然为我们的可视化团队服务。原来的 25 个班级今天仍然存在于系统中。

作为读者,我们希望您能从我们在可视化系统设计方面的经验中受益。我们试图通过在每一章的全部放在一起部分中描述许多Visualization Toolkit类的属性(属性和方法)来帮助您。还包括由 Doxygen 文档系统生成的一系列对象图,可以让您快速了解对象关系,例如超类和子类。该文档可以在 CD-ROM 上找到,也可以在http://www.vtk.org上在线找到。在下一章中,我们还将解释我们为设计 VTK 面向对象工具包所做的决定。

2.8 章节总结

本章介绍了面向对象的概念和术语。重点是处理复杂性以及面向对象技术如何提供降低软件复杂性的机制。

模型构建是任何设计方法的重要组成部分。我们介绍了三种模型和符号。对象模型描述系统中的对象及其静态关系、属性和方法。对象图简洁地呈现了这种静态信息。动态模型侧重于系统的时间相关方面。状态转换图用于对系统的顺序和控制部分进行建模。功能模型显示系统中的对象如何转换数据或其他对象。数据流图是一种方便的表示函数依赖关系的符号。

今天有多种选择可用于面向对象的实现。尽管可以用非面向对象的语言(如 C)实现面向对象的系统,但该方法最好由面向对象的语言提供。我们选择了 C++ 来实现可视化工具包

本书的重点是架构、数据结构设计和算法。系统的面向对象方面很重要,但系统所做的事情要重要得多。

2.9 书目注释

有几本关于面向对象设计的优秀教科书。[Rumbaugh91][Birtwistle79]都提出了与语言无关的设计方法。这两本书都强调建模和图表是设计的关键方面。[Meyer88]还描述了 Eiffel 上下文中的 OO 设计过程,这是一种 OO 语言。Booch [Booch91]撰写了另一本受欢迎的书。

任何想成为面向对象设计和实现的认真用户的人都应该阅读Xerox Parc 的 Smalltalk 开发人员关于 Smalltalk [Goldberg83] [Goldberg84]的书籍。在另一本早期的面向对象编程书籍中,[Cox86]描述了 OO 技术和编程语言 Objective-C。Objective-C 是 C 和 Smalltalk 的混合体,Next Computer 使用它来实现他们的操作系统和用户界面。

有很多关于面向对象语言的文章。CLOS [Keene89]描述了通用列表对象系统。[Meyer88]描述了 Eiffel,一种强类型的 OO 语言。Objective-C [Cox86]是一种弱类型语言。

由于 C++ 已成为一种流行的编程语言,现在有许多类库可用于应用程序。[Gorlen90] 描述了一个基于 [Goldberg83] 中描述的 Smalltalk 类建模的集合和数组的扩展类库。[Stepanov94] 和 [Musser94] 描述了标准模板库,这是一个数据结构和算法的框架,现在是 ANSI C++ 标准的一部分。Open Inventor [Inventor] 是一个支持交互式 3D 计算机图形的 C++ 库。Insight Segmentation and Registration Toolkit (ITK) 是一个相对较新的类库,通常与 VTK [ITK] 结合用于医疗数据处理。VXL 是一个用于计算机视觉研究和实现的 C++ 库 [VXL]。还提供了几个数学库,例如 VNL(VXL 的一部分)和 Blitz++ [Blitz]。

C++ 文本比比皆是。C++ [Stroustrup84]作者的原始描述对于任何认真的C++程序员来说都是必须的。另一本书 [Ellis90] 描述了该语言的标准扩展。最近UML系列丛书[Booch98]和[Rumbaugh98]相当火爆,是极力推荐的资源。几本关于泛型编程 [Austern99] 和 STL [Musser96] 的书也很有用。与您的同事一起查看他们最喜欢的 C++ 书籍。

为了与新的发展保持联系,有会议、期刊和网站。面向对象主题的最强技术会议是一年一度的面向对象编程系统、语言和应用程序 ( OOPSLA ) 会议。这是该领域的研究人员描述、教授和辩论面向对象技术的最新技术的地方。SIGS Publications, NY 出版的双月刊《面向对象编程杂志》 (JOOP) 介绍了该领域的技术论文、专栏和教程。万维网上的资源包括 Usenet 新闻组comp.objectcomp.lang.c++

2.10 参考文献

[Austern99] MH 奥斯特恩。通用编程和 STL。艾迪生-韦斯利 1999 年。ISBN 0-2-1-30956-4。

[Birtwistle79]通用汽车 Birtwistle、O. Dahl、B. Myhrhaug 和 K. Nygaard。模拟开始。Chartwell-Bratt 有限公司,英国,1979 年。

[闪电战] http://www.oonumerics.org/blitz/

[Booch91] G. Booch。带有应用程序的面向对象设计。本杰明/卡明斯出版公司,加利福尼亚州红木城,1991 年。

[Booch98] G. Booch,I. Jacobson,J. Rumbaugh。统一建模语言用户指南。艾迪生-韦斯利 1998,国际标准书号 0201571684。

[考克斯86] BJ考克斯。面向对象编程:一种进化方法。Addison-Wesley,马萨诸塞州雷丁,1986 年。

[Ellis90] M. Ellis 和 B. Stroustrup。带注释的 C++ 参考手册。Addison-Wesley,马萨诸塞州雷丁,1990 年。

[戈德堡83] A.戈德堡,D.罗布森。Smalltalk-80:语言及其实现。Addison-Wesley,马萨诸塞州雷丁,1983 年。

[戈德堡84] A.戈德堡。Smalltalk-80:交互式编程环境。Addison-Wesley,马萨诸塞州雷丁,1984 年。

[谷歌] http://www.google.com

[Gorlen90] K. Gorlen、S. Orlow 和 P. Plexico。数据抽象和面向对象编程。约翰威利父子公司,英国奇切斯特,1990 年。

[发明家] http://oss.sgi.com/projects/inventor/

[ITK] Insight 软件联盟。http://www.itk.org

[基恩89] S.基恩。Common Lisp 中的面向对象编程:CLOS 程序员指南。Addison-Wesley,马萨诸塞州雷丁,1989 年。

[Lorensen89]我们 Lorensen,B. Yamrom。“面向对象的计算机动画”。IEEE NAE-CON 会议记录,2:588-595,俄亥俄州代顿,1989 年 5 月。

[Margulis88] L. Margulis 和 KV Schwartz。五个王国地球上生命门的图解指南。H. Freeman & Co.,纽约,1988 年。

[迈耶88] B.迈耶。面向对象的软件构建。Prentice Hall International,英国赫特福德郡,1988 年。

[Musser94] D. Musser 和 A. Stepanov。“面向算法的通用库”。软件实践和经验。24(7):623–642,1994 年 7 月。

[Musser96] DR Musser 和 A. Saini。STL 教程和参考指南。艾迪生-韦斯利 1996.ISBN 0-201-63398-1。

[Rumbaugh91] J. Rumbaugh、M. Blaha、W. Premerlani、F. Eddy 和 W. Lorensen。面向对象的建模和 设计。Prentice Hall,恩格尔伍德悬崖,新泽西州,1991 年。

[Rumbaugh98] J. Rumbaugh、G. Booch 和 I. Jacobson。统一建模语言参考手册。艾迪生-韦斯利 1998 年,国际标准书号:020130998X。

[Schroeder92] WJ Schroeder、WE Lorensen、G. Montanaro 和 C. Volpe。“Visage:面向对象的科学可视化系统。” 在可视化论文集 ’92中。第 219–226 页,IEEE 计算机协会出版社,加利福尼亚州洛斯阿拉米托斯,1992 年 10 月。

[Stepanov94] A. Stepanov 和 M. Lee。标准模板库。ISO 编程语言 C++ 项目。博士。编号 X3J16/94-0095,WG21/N0482,1994 年 5 月。

[Stroustrup84] B. Stroustrup。C++ 编程语言。Addison-Wesley,马萨诸塞州雷丁,1986 年。

[VXL] http://vxl.sourceforge.net/

© 版权声明
THE END
喜欢就支持一下吧
点赞5154 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容