第3章
一个迫切需要灵活代码的问题
概述
本章对我们要解决的一个问题给出了一个概述:从一个大型CAD/CAM数据库析取信息去侍服一个复杂昂贵的分析程序。由于该CAD/CAM系统持续演化,这个问题迫切需要灵活的代码。
在本章,我对CAD/CAM问题、该领域的词汇表,以及问题的重要特性给出了一个概述。
从一个CAD/CAM系统析取信息
在此要复习我以前的一个设计,是它引领着我,让我得到本书所包含的这些洞察力。
那时候我在一个设计中心做支持工作。在那里,工程师使用一个CAD/CAM系统为金属板部件作画。图3-1显示了这些部件中的一个例子。
我的问题是写一个电脑工具从该CAD/CAM系统中吸取出信息,以供一个专家系统以一种特定的方式来使用。这个专家系统需要这些信息来控制部件的制造。由于它修改起来十分复杂而且将会比当前版本的CAD/CAM系统有更长的寿命,因此我希望所写的信息吸取工具能够很容易地适应这个CAD/CAM系统的修订版本。
图3-1 一片金属板的例子
什么是专家系统?
专家系统是一个特殊的计算机系统,它使用人类专家的规则去做出自动化的决策。构建专家系统包含两个步骤。首先,取得专家用于决策和完成任务的规则集。接着,在计算机系统中实现该规则集;这一步通常使用某种商业可用的专家系统工具。对分析者而言,第一步是远远更加困难的任务。
理解词汇表
分析中的第一个任务是理解问题领域中的用户和专家所使用的词汇表。那些被使用到的最重要的术语用于描述金属板的尺寸和几何。
如图3-1所示,一片金属板被切割成特定的大小并从中切割出形状。专家们使用通用名“特性”来称呼这些剪切块。一片金属板可通过它的外部尺寸和它所包含的特性而完全指定。
表3-1描述了在一片金属板中可以找到的形状的类型——特性。它们是系统必须要处理的形状。
表3-1 在一片金属板中可找到的形状
形状
描述
槽
在金属上以常量宽度纵切,以方角或者圆角边缘结束。槽可以朝向任何角度。通常使用一个曲槽刨头来切割它们。图3-1的左边有三个槽;一个水平朝向,其它两个垂直朝向。
洞
金属板上的圆形切割。一般用宽度变化的钻头来切割它们。图3-1左边有一个洞被三个槽包围着,在金属板的右边还有一个大洞。
剪切块
方角或圆角边缘的方块。用一个高压穿孔机以巨大的冲力冲击金属板切割而成。图3-1有三个剪切块;其中右下方的一个是45度朝向。
特殊形
不是槽、洞或者剪切块的预成型形状。此时会制造一个专门的打孔机来快速地创造它们。电源插座就是一个普通的“特殊形”实例。图3-1中的星形形状是一个特殊形形状。
不规则形
任何其它形状。使用组合工具来创造它们。图3-1右下方的那个不规则形状的物体就是一个不规则形形状。
CAD/CAM专家同时也使用表3-2中的额外术语,它们对于理解十分重要。
表3-2 额外的CAD/CAM词汇
术语
描述
几何
对一片金属板外观的描述:每一个特性的位置和尺寸,以及金属板的外部形状。
部件
金属板自身。我需要能够存储每一个部件的几何。
数据集或模型
CAD/CAM数据库中用于存储一个部件几何的记录集。
NC机和NC集
数控(NC)机。一个专门的制造工具,它被计算机程序控制,使用各种切割头去切割金属。通常,计算机程序被输入部件的几何,它由称为NC集的一组命令组成。
描述问题
我要设计一个程序,它允许专家系统打开并读取一个模型,后者包含一个部件的几何。我希望分析这个部件的几何,并为数控(NC)机产生命令以构建这片金属板。
在这个例子中,我只关心金属板部件。当然,这个CAD/CAM系统也能够处理许多其它种类的部件。
从高层次上来看,我希望这个系统能够执行以下步骤:
l 分析金属片。
l 基于这些金属片所包含的特性看看应该如何产生它们。
l 产生一组能被制造设备阅读的指令。这组指令被称作一个NC集或数控集。
l 在我想要产生这些部件中任何部件时,将这些指令发送到制造设备。
这项编程任务的困难之处在于我不能从数据集中简单地析取出特性并产生NC集命令。这些要被使用的命令,它们的类型以及它们被使用的次序依赖于那些特性以及特性和其它特性的关系。
举个例子,我们来看一个由几个特性组成的形状:
图3-2 一个带有两个槽的剪切块。左边:该部件完成时的样子。右边:实际上它由三个特性组成。
事实上,为组成左边的形状,我需要得到右边的三个特性。意识到这一点尤为重要。因为使用该CAD/CAM的工程师通常是基于特性来考虑如何组成复杂的形状。他们知道这样做会使得部件的制造更快。
问题是我不能够不考虑这三个特性彼此间的关系就产生NC集命令并希望正确地产生部件——这里通常存在一个特定次序的问题。在这个例子中,如果我像图3-3显示的一样,先产生槽然后产生剪切块,那么在产生剪切块时(记住,剪切块是使用高压穿孔机产生的)这片金属板就会弯曲,因为槽会首先削弱金属板的抗击打能力。
图3-3 一个失败的切割方法。这样的次序会产生弱化的、弯曲的金属板。
要创建图3-2中显示的形状,我必须先为剪切块打孔,然后才是为槽打孔。这样做是可行的,因为槽是用曲槽刨运用侧力产生的。就像图3-4显示的那样,事实上先产生剪切块使得这项工作更加容易,而不是更难。
幸运的是,已经有人为专家系统制定了规则。我不用为这担心。我花时间来解释这些复杂的问题是想让你能够理解专家系统需要何种信息。
图3-4 专家的切割方法。这种方法会产生正确的剪切块。
重要的挑战和方法
这个CAD/CAM系统在不断地演化、改变。我面临的真正问题是在该系统改变时让公司有可能继续使用那个昂贵的专家系统。
我的处境是这样的:他们当时正在使用CAD/CAM系统的一个版本V1,而一个新版本V2将很快就会产生。虽然这两个版本是由一个销售商提供的,但它们却并不兼容。
由于各种技术和管理上的原因,不可能将模型从一个版本翻译到下一个版本。因此,这个专家系统需要能够支持CAD/CAM系统的两个版本。
事实上,和不得不包容CAD/CAM系统的两个不同版本相比,情况还要更差。我知道不久以后第三个版本又将面世,但却不知道这件事将会在何时发生。为了保存公司在专家系统上的投资,我想使用近似图3-5所示的系统构架。
图3-5 我的解决方案的高层视图
换句话说,应用程序能够初始化每一样东西,以便专家系统能够使用合适的CAD/CAM系统。不过,专家系统必须有能力使用其中任何一个版本。因此我需要使得对专家系统而言,V1和V2看起来都是一样的。
在几何吸取器层次是肯定需要多态的,但在特性层次却不需要。这是因为专家系统需要知道它处理的是哪一种类型的特性。然而,我们不想在CAD/CAM系统的V3出现时对专家系统做任何改变。
对面向对象设计的基本理解暗示着我将会拥有一个类似于图3-6所示的高层类图。
也就是说,专家系统通过Model类和CAD/CAM系统相关联。Main类负责这初始化Model的正确版本(即V1Model或者V2Model)。
现在,我将描述这两个CAD/CAM系统以及它们如何工作。很不幸,它们是非常不同的令人讨厌的家伙。
图3-6 我的解决方案的类图。[1]
版本1本质上是一组子程序库。为了从模型中得到信息,必须进行一系列的调用。一组典型的查询如下:
步骤
在CAD/CAM 版本1中做
1.
打开模型XYZ并返回它的一个句柄
2.
将这个句柄存储为H
3.
对H引用的模型,告诉我有多少特性,将它存储为N
4.
对H引用的模型中的每一个特性(从1到N)
4a.
对H引用的模型,告诉我第i个元素的ID,将它存储为ID
4b.
对H引用的模型,告诉我ID的特性类型,将它存储为T
4c.
对H引用的模型,告诉我ID的X坐标值,将它存储为X(基于类型,使用T来决定调用正确的例程)
这个系统让人难以相处,很显然它不是面向对象的。不管谁来使用这个系统,他都必须手工地为每一次查询维护上下文。每一个有关特性的调用必须知道它使用的是何种特性。
CAD/CAM销售商意识到这类系统固有的局限性。他们构建V2的首要动机就是要把它做成面向对象的。因此V2中的几何存储于对象之中。当系统请求一个模型,它便返回一个代码模型的对象。这个模型对象包含一组对象,每一个对象代表一个特性。由于问题领域是基于特性的,那么V2用于表达这些特性的类和我曾经提及的特性:槽、孔、剪切块、特殊形以及不规则形是一一对应的也就不足为奇了。
因此,在V2中,我能够得到一组对象,它们和存在于金属板中的特性相对应。图3-7中的UML图显示了这些特性类。
图3-7 V2的特性类
其中,OOG代表面向对象的几何,它仅仅用于提醒V2是一个面向对象的系统。
总结
在本章,我描述了CAD/CAM问题。
l 我必须用同样的方法从不同的CAD/CAM系统中析取信息。这将允许公司一个投资巨大的系统(专家系统)在每当CAD/CAM系统改变时不需要昂贵的修改而能继续工作。
l 我有两个系统,虽然它们包含完全相同的信息,但它们的实现方法却截然不同。
这项任务和我在项目中碰到的其它问题存在许多相似之处。那里有着实现不同的特殊系统,但我希望允许其它对象使用同样的方式和这些不同的实现通信。
[1] 这张图以及本书中的全部其它图都使用统一建模语言(UML)标记法。见第二章“UML——统一建模语言”,可得到UML标记法的描述。