类框架设计问题(100分)

  • 主题发起人 主题发起人 Gooder
  • 开始时间 开始时间
G

Gooder

Unregistered / Unconfirmed
GUEST, unregistred user!
http://expert.csdn.net/Expert/topic/1139/1139218.xml?temp=.3015253
希望有高手为我指路
 
引自Gooder的http://expert.csdn.net/Expert/topic/1139/1139218.xml?temp=.3015253
我的类框架里是这样子的。
Collects = class
public
FCollects : array of BASE;
end;

BASE = class
public
procedure ABC;
abstract;
end;

Derived1 = class (BASE)
private
procedure DEF;
public
procedure ABC;
end;

Derived2 = class (BASE)
private
procedure GHI;
public
procedure ABC;
end;

如果说我要在Derived2中添加一个新功能NEWFUN,而且该功能需要暴露于外界成为一个接口,以便在Collections类中调用,
那么我应该怎么办?在BASE类中新建一个接口NEWFUN后,再在Derived1中添加一个实现NEWFUN的函数吗?这种方法如果在
子类不多的时候还可接受,但是如果子类一但多起来,那如果哪一个子类需要向外界暴露多一个接口,都必须要在所有的
同层次的子类中实现对它自己无用的该接口,这样子不是很麻烦?
 
非常感谢dedman同志帮我把这个问题贴过来,希望有跟多的朋友帮我解决问题.
同时从这个问题中,我发现设计模式有很多时候都是用到接口来实现的.
那如果我的接口不能统一确定,或者说我的接口到将来有可能需要添加功能,
那如何进行这种设计模式.
 
我觉得有两点要考虑清楚,一是BASE<-Derived1,Derived2的类层次上,是不是真的能抽象出
BASE类。如果子类新增加的功能相近,可在BASE的public中,声名一个方法(如NewFun),里面
调用一个protected,virtual的方法(如doNewFun),这个方法可由子类重载。二是调用BASE的
Collects类上,能不能增加子类,使层次与BASE那边相对应。
 
您让我考虑的第二点我不是太明白。
至于是不是真的能抽象出BASE类,那我就想请教一下您:
像电话类群,基类为Telphone,它分别有两个子类:
座机StationTelphone、和手机MobileTelphone,它们的共同功能打电话、听电话,
当然是可以抽象到基类Telphone里面,再由子类实现。
但是手机还有新功能:发短信息,而这个功能在座机里面是没有的,如果把这个功能
抽象到基类,那么座机又不得不为这个功能提供一个空函数,因为我是以Telphone基类作
为接口让外界调用的,即使用Tels : array of Telphone来管理手机的。
那么我想问一问你,座机和手机是否能抽象成为一个类,它们的主要功能打电话、听电话
是差不多的,只是一个发短信息功能不一样而导致两个类不能抽象成为一个类吗,我觉得
应该有方法解决这种问题的。
 
试试通过一个域来控制
SendMsg:Boolean;
//=================
if SendMsg then
//发短信
else
//引发错误
 
喔,ysai这个方法可以实施,不知道还有没有其他方法呢?
 
我说的第二点主要是Telephone类的调用者这边,因为你这时的情况是尽管抽象出一个基类,
但却无法使Telephone类的调用者Collects只面对这个基类,比如有些调用者是要使用MobileTelephone
的发短信功能,那就可考虑增加Collects的子类(如CollectsMobile),这样共有的功能可
在Collects处理而特殊的则下放到CollectsMobile.
一点看法,再听听其他人的。
 
>>在BASE类中新建一个接口NEWFUN后,再在Derived1中添加一个实现NEWFUN的函数吗?这种方法如果在
子类不多的时候还可接受,但是如果子类一但多起来,那如果哪一个子类需要向外界暴露多一个接口,都必须要在所有的
同层次的子类中实现对它自己无用的该接口,这样子不是很麻烦?
有一种方法可以解决,也就是说,你可以把NEWFUN在基类中定义成virtual,而不是abstract。
这样,NEWFUN在基类中就必须实现,不过他的功能很简单,就是引发一个错误。
如果某个子类需要实现此功能可以覆盖它。不需要的则不必覆盖。
拿Telphone来说,你可以在Telphone中实现Sendmsg,不过代码只是引发一个错误。
StationTelphone因为无此功能,所以没有覆盖,调用Sendmsg将出错。而MobileTelphone覆盖了Sendmsg,
则可以正常调用。


 
呵呵,我昨晚听到ysai的方法之后,回去仔细考虑想到的方法,想不到今天就已经被mywyn
提了出来,真是高人啊。
我已经把我的设计用静态图表示出来并附上原码,如果想要的,就留个EMAIL吧。
但是这个设计让我想到另一个问题,就是在基类Telephone中如果把SendMsg放入作为接口
那么好像有点违返了OO的规则。因为既然Telephone即然有这个接口,就应该实现它,但
是有的子类并没有实现却发出一个错误信息,这样子是不是有点问题呢?
 
不知道如何把硬盘上的图片贴到论坛上呢?
 
to Gooder:
高人我还算不上,只是大家共同探讨而已。
至于你说的违返了OO的规则,我觉得没有。在C++和Delphi中都曾大量使用。
如果你觉得基类只能抽象个体的共同行为,那么用OO编程会很累!
 
非常好,我结帖了。
在此很感谢dedman,mywyn,ysai三位大侠的帮助和指导。
在此附上我的Email地址:GooderNormal@21cn.com,愿跟你们做朋友,不知你们的意下如何。
(QQ号不方便公开,若愿意请发个信给我,我再告诉你们)
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
824
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部