相关类的设计

对象和类

对象是存在于现实世界中的事物或关系,而类是描述对象的代码集。比如树是对象,Tree类是描述树这个对象的代码集。

形成类的前提是有可描述的对象。而对象常常隐藏在纷繁复杂的表象中,有经验、有洞察力的人才能发现它,并把它提取出来。对象本身是客观存在的,但对象的提取方法不是惟一的,它与要处理的问题有关,与解决问题的方法有关。

对象被提取出来以后,它不是孤立的,它要与其他对象发生联系。如何处理对象之间的关系,是对象的组织问题。如果把单个的对象比做黑白世界里的棋子,那么对象的组织就好象是布一个局,可以有很多变化。围棋中有定势,对象组织也有定势。

对象的提取完成以后,用计算机语言描写出来,就是类。而对象的组织相应地要用有组织的类来描述。

所以,进行交互式CAD系统设计以前,需要首先提取出必要的对象,包括基本的图元对象和定义交互操作的对象,然后用语言来描写它们。

基本图元类设计

为了描述各种基本的图形元素,必须进行图元类的设计。作为图元来讲,它们有很多共同点,比如都有颜色、样式(线型或文本格式)和大小,交互绘制时都要进行拾取、平移、旋转、镜像、缩放和绘制等。所以有必要创建一个图元基类CGElement。把该基类定义为抽象类,必须继承;将共有的方法设置为抽象方法,必须在派生类中重写。本书最后提供的CAD小系统中包含有直线段、矩形、圆、圆弧和文本等5种图元,对应地创建了CLine类、CRectangle类、CCircle类、CArc类和CText类。这些类都从CGElement类继承,其UML 图如图2-1所示。第3章将详细介绍基本图元类的设计。

Document Image
\[\]

图2-1 基本图元类的UML图

交互绘图类设计

基本图元类对图元的基本特征和行为进行描述,但仅仅依靠它们还不够,因为在交互式CAD系统中,确定图元形态的数据(如直线段的端点坐标等)不是预先给定的,而是在绘制的过程中通过命令窗口或鼠标即时输入的。所以,还需要对交互绘制图元时的整个过程进行描述。这个过程是一个动态的过程。例如,绘制直线段时,首先在绘图区单击鼠标左键,确定了直线段的起点,然后移动鼠标,移动时要动态地显示直线段的当前状态;再次单击鼠标左键时,把直线段的终点确定下来,完成绘制。有了这样一个描述以后,绘图工作就变得有趣了,也更方便了。

为了描述交互绘图的过程,必须创建交互绘图类。用鼠标绘图时,总是涉及到按键和移动等操作。所以,有必要创建一个接口或抽象的基类来定义这些操作行为,为具体的操作提供模板。本书中创建了一个ICommand 接口,它有3个方法:LbuttonDown, MouseMove和RButtonDown,分别定义鼠标左键按下、移动和右键按下时的绘图行为。然后有9个交互绘图类实现了ICommand接口,即CCreateLine类、CCreateRect类、CCreateCircle类、CCreate Arc类、CCreate Text类、CMove类、CRotate类、CMirror类、CSelect类,分别实现直线段、矩形、圆、圆弧、文本的创建,对选定图元的平移变换、旋转变换和镜像变换,以及选择图元。

如图1-2所示,各类与ICommand接口之间是接口关系。也可以把ICmmand接口用一个抽象基类CCommand替换,然后,后面各类从它那里继承。两种方法在性能上并没有明显的区别,但这里主要强调的是行为的相似性,所以定义为接口。

交互绘图类的设计在第4章进行具体介绍。"

Document Image
\[\]

图2-2 交互绘图类的UML图

类的交互

其实,类的交互问题已经比较清楚了。当客户端(菜单项或命令按钮)调用交互绘图类进行绘图时,交互绘图类必然要创建基本图元类的实例并调用它的方法。描述一个一般的操作,如创建一条直线段,选中它,然后平移它,其步骤大致如下。

(1) 首先发出创建直线段的指令,调用CCreateLine类进行具体实施。第1次单击鼠标左键确定直线段的起点以后,移动鼠标时要绘制起点到鼠标光标当前位置的直线段(橡皮线),绘制橡皮线就需要创建CLine类的实例,然后调用该实例的Draw方法完成绘制。

(2) 选择直线段时使用CSelect类,需要计算当前鼠标光标点到直线段的距离,判断直线段是否被拾取。此时需要从保存图元的集合类中通过索引找到该直线段对象,然后调用它的Pick 方法进行判断。如果被拾取,则用Draw方法,用某种其他的颜色或线型重画直线段。

(3) 选中图元以后,可以进行平移操作。指令发出以后,用CMove类完成。此时要调用被选中的直线段对象的Move方法移动直线段并重新显示。