发信人: leeyg()
整理人: majorsun(2000-07-28 13:05:35), 站内信件
|
你可以引用本文,但请注明作者,并请注明出自本论坛。
请大家指正。
界面类的合并
很多的情况下,在我们进行界面设计时,会遇到这样的情况:
1、 界面完全一样,但是实现的功能不同
这种情况最典型的例子就是“增加子界面”与“修改子界面”,
两个功能子界面的外观完全一样,只是在功能上略有不同:增
加时所有的录入栏为空,修改时为原值;按动“存盘”按纽时
可能会因功能的不同而有不同的处理。
2、 界面中大部分外观相同,只有小部分不同,当然其界面所实现
的功能也不相同。
一个典型的例子是在一个进销存系统中,“水果”类的“录入
子界面”与“(水果)实例子界面”的界面大部分外观都相同。
在这两个界面之间,“录入子界面”有“存盘”、“取消”按
纽,“(水果)实例子界面”有“修改”、“关闭”按纽,除
了按纽的不同外,其它的大部分界面完全相同。
这两种情况,我们在设计界面时,如何看待,我们是否应该为这些
外观区别不很大的界面分别设计一个Form?如果不是,又该怎样合并?
在面向对象的系统分析及设计中,界面是由一个或多个在系统运行
时具有外观形状及控制的控件组成的,界面本身也是个类,界面类及其
所组成的类树与OOD的分析结果之间是软件复用的关系,界面类与其所
反映的OOD类之间的关系是实例连接的关系。(详见《面向对象的系统
分析与面向对象的可视化开发工具》)。
正常的思路下,是为每一个界面都设计一个Form,每一个Form中都
有一个Ttable或Tquery以体现这个实例连接。
应该说,这的确是一种清晰的解决方案,最原始的方法应该如此。
但是,这种方法存在这些缺点:
(1) Form的数量多,不易管理与维护;
(2) 资源占用大,系统庞大;
(3) 仅将可视化开发工具看成了纯粹的界面开发工具,没有充分利
用其便利性
(4) 忽略了系统(导航)界面。(通常就是如主菜单等引导用户操
作的系统界面)
我们先来探讨一下如何合并这些Form。
在DELPHI中,可以将多个控件组成一个视觉外观的,除了Form类,
还有最常用的Panel类。因此,在DELPHI中,一个可行的方案是:将界面
分类为主界面与功能子界面,主界面与功能子界面共同组成某个OOD主题
的界面。主界面只有一个,由一个或多个功能子界面组成。主界面由Form
及Form上的可视化控件组成,功能子界面由Panel及Panel上的可视化控
件组成。
上面的问题一中,由一个Form作为反映OOD主题(联系人通讯录、
联系人类及这两个类之间的关系)的主界面,设计“增加子界面”
PanelInsert、“修改子界面”PanelModify作为联系人通讯录主界面
的功能子界面,这两个功能子界面均存在于同一个Form中,作为Form
的属性。体现主界面与功能子界面的整体-部分关系。
这样,我们合并了不同的Form。
但是问题仍还没有彻底解决,我们是否应该为这些相外观区别不
很大的界面分别设计一个功能子界面Panel?很显然,为这些仅有细微
差别的功能子界面而分别设计,甚至仅仅因为功能不同(如问题一)
而设计两个具有完全一样的外观的功能子界面是不合理的。我们要探
讨一下如何再将它们进行合并。
我们先来看看这两个问题的实质。
如上所述,在面向对象的系统分析及设计中,界面是类,功能子
界面虽然在实现上由在Panel上放置可视化的控件而完成,但在逻辑上,
功能子界面也是类,Panel上的各个控件是功能子界面类的属性,
Panel本身可看作是Form的另一种group控件的界面形式。
所以,上述的两个问题,其实质应该归纳成这样:
1、 属性一样但方法不同的类如何合并。
2、 属性大部分相同但方法不同的类如何合并。
假定有这么4个类,其中类A、类B为问题1的讨论类,类C、类D为问
题2 的讨论类。
(图一)
根据OO的思想,我们首先想到是,既然类A与类B之间有相同的属性
与方法,那么应该将它们“抽象”出来,组成一个新类,叫类E,类A、
类B分别再从类E中派生出来。同理,类C与类D之间也是如此。这样,我
们得出这样的类图:
(图二)
然而,实际上,在用DELPHI进行的OOP中,这样的类图很难实现。
主要体现在DELPHI并不支持Form的派生类以下的可视化编程。也就是
说,如果E、F类是从Form中派兵的第一代继承的话,E、F可以进行可
视化编程,可以在E、F类的Form中放置按纽、Panel等等并进行可视化
编程;但是,从E、F派生的第二代继承类A、B、C、D,则不再支持它
们的可视化编程,当我们在设计阶段用TA=Class(TE)企图在屏幕上出
现TE的画面并在此基础上再进行可视化开发,再放些按纽等控件时,
DELPHI并不能做到,这样,可视化编程的优越性得不到充分体现,大
大加大了OOP的难度。
我们可以用DELPHI提供的比如将TE变成一个控件来进行二次开发
等等的方法来实现,但是,运用DELPHI的IDE环境来解决这个问题,
却使OOP与OOD产生了脱节,OOD中的各个类及其类树在OOD中得不到切
实的体现,使一气呵成OO的设计实现受到阻滞。
怎样解决这个问题?我们知道,类与类之间的一般-特殊关系
(即继承关系),可以通过整体-部分关系来实现。一般-特殊关系
是使特殊类通过继承而拥有一般类的特征,整体-部分关系是使整体
对象通过组装而拥有部分对象的特征。尽管途径不同,着眼点不同,
结果却是一样的:一些对象拥有另一些对象的特征。正像我们所说:
“子女通过遗传(继承)而拥有父亲和母亲的血统”,也可以说:
“子女的血统,是由父亲和母亲两种血统构成的”。说法不同,实
质内容是一样的。
我们尝试将这2个问题的一般-特殊关系用整体-部分关系来实
现,将类A、类B中的共性部分抽象出来组成一个类C,并在类A、类B的
属性中增加一个属性“对象C”以体现这一整体-部分关系,得出另一
个解决方案:
(图三)
这样的结构,既使OOD中的类及类树在OOP中得到充分的体现,同
时,在OOP中又非常容易实现。
考虑类A与类B,属性完全相同仅方法不同的两个类,如果A的独
有方法及B的独有方法在数量很少,在OOA阶段,即是应该精简的对象,
应该考虑合并。对于“增加子界面”与“修改子界面”个案来说,两
个子界面仅是“存盘”的操作可能不同(“增加子界面”的存盘可能
会发消息通知别的类“某某对象增加了一个”),连“取消”的操作
(方法)都是相同的,因此,只有一个属性或只有一个方法的类,原
则上是应该在OOA层面上精简的类。
因此,结合上面的问题,其解决方案如下:
问题1:“增加子界面”与“修改子界面”完全合并,通称为
“录入子界面”,在“存盘”操作(方法)中设立区分是增加的存盘
还是修改的存盘。分别调用增加的存盘(类A中的方法)及修改的存盘
(类B中的方法)。
问题2 :将“录入子界面”与“(水果)实例子界面”中显示水果
属性的部分,也就是大部分外观都相同的部分,抽取出来放到一个新
Panel中,由这部分外观(控件)与这个Panel组成一个功能子界
面(类F),假定我们称它为PanelFruit。在“录入子界面”中设
“存盘”、“取消”按纽及一个能够体现连接PanelFruit的变量,同
样,“(水果)实例子界面”有“修改”、“关闭”按纽,也有一个
一个能够体现连接PanelFruit的变量。
至此,我们可以看出,其实这里所谓的合并,其实就是我们常说
的“抽象”,本文之所以不称它为“抽象”仍然称为合并,是因为它
除了我们完成了一般的“抽象”动作外,我们还进一步地用“整体-
部分”结构表达了体现“抽象”动作的“一般-特殊”结构。
从上面的PanelFruit子界面可以看到,根据这一思路,功能子界
面之中如果觉得仍然有必要再进行抽象(合并)时,可在功能子界面
中定义再下一层的功能子界面,也就是说,Panel下可再有界面意义的
Panel。
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.35.224]
|
|