一个类关系设计上的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 Reesinx
  • 开始时间 开始时间
R

Reesinx

Unregistered / Unconfirmed
GUEST, unregistred user!
因这里不能帖图, 我给出两个链接:
http://voidclass.googlepages.com/citd1.JPG
http://voidclass.googlepages.com/ctid2.JPG

问题出在第2张图上, 主要是两个类互相包含的问题。

我写一个TDeviceMgr类,这个类是一个语音卡管理类。
还有一个TIVRMgr类,主要用于IVR逻辑处理,比如,用户把电话打出系统后,按1程序如何处理,按2程序如何处理。这个地方我想先写一个类,然后下一版本的时候考虑改用Python脚本来写,但是现在项目时间紧张,写成一个类。
再有就是一个TSocketSvr类,主要负责管理语音服务器与坐席之间的通讯。

现在问题出现了,在TDeviceMgr类中要使用到TIVRMgr对象和TSocketSvr对象,而在TIVRMgr和TSocketSvr类中又要用到TDeviceMgr对象,这样就出现类的互相包含。在Delphi中是不允许将这三个分开写在三个单元中的,只能写一个单元中。而写在一个单元中又不利于封装。

请问一下,是我设计上出了问题还是可以通过其他方法还实现将这三个类分别放在各自的单元中?

关于这些类的设计的更详细信息,我放在网站上了。
http://www.voidclass.com/doc/index.html
 
这个很容易实现的啊
TDeviceMgr = class
FIVRmgr: TIVRmgr;
FSocketSvr: TSocketSvr;
...
constructor Create;
begin
...
FIVRmgr := TIVRmgr.Create(Self, ......);
FSocketSvr := TSocketSvr.Create(Self, .....);
...
end;
在TIVRmgr,TSocketSvr类的创建中只要传一个TDeviceMgr 类型的参数就可以了

不建议使用“友元”,实际上它破坏了对象之间的独立性
 
unit DeviceManager;
...
uses IVRManager, SocketServer;
...
TDeviceMgr = class
FIVRmgr: TIVRmgr;
FSocketSvr: TSocketSvr;
...
constructor Create;
begin
...
FIVRmgr := TIVRmgr.Create(Self, ......);
FSocketSvr := TSocketSvr.Create(Self, .....);
...
end;
-------------------------------------------------------------------
unit IVRManager;
...
uses DeviceManager;
...
TIVRMgr = class
FDeviceMgr: TDeviceMgr;
...
constructor Create(DeviceMgr: TDeviceMgr);
begin
...
FDevcieMgr := DeviceMgr;
...
end;
--------------------------------------------------------------------------
上面DeviceManager和IVRManager两个单元互相uses, 在Delphi中是不允许的!
 
面向对象设计中的一个原则是低耦合高内聚,保持每个对象的相对独立性。
楼主的三个对象有较强的耦合,但又想保持一定的独立性。
我建议可以使用一个公共的接口单元,即把三个类中相互耦合的部分全部放到这个单元里,定义成抽象虚函数,三个类的实现单元引用这个单元即可调用相应功能。
例:
unit Kt_Interface;
....
TIDeviceManage = class(TObject)
protected
FDeviceList: TThreadList;
public
constructor Create(MsgThreadID: HWnd); virtual; abstract;
function AddDev(DeviceID: Byte; SysConfig: TSysConfig): Boolean; virtual; abstract;
function FindDev(DeviceID: Byte; var Device: TILipDevice): Boolean; virtual; abstract;
function CheckDeviceRun: Boolean; virtual; abstract;
property DeviceList: TThreadList read FDeviceList;
end;

Unit DeviceManage
.....
TDeviceManage = class(TIDeviceManage)
.....
 
To LZ
"上面DeviceManager和IVRManager两个单元互相uses, 在Delphi中是不允许的! "
谁说的?
你把一个uses放在原来的位置
把另一个单元的uses放在 implementation 下面看看
 
to nicai_wgl:
有点晕, 还没开窍!!!
你的意思是第个类都提取出一个接口类吗? 然后呢?
麻烦你再给讲讲! 谢谢!
 
to themars:
是的, 你说的是对的, 但是在我的程序中, 在两个类的定义部分中就使用到了另外一个类, 所以没办法把uses写在implementation下面. 请注意看一下我上面写的Demo code.
 
to nicai_wgl:
另外, 如果说, 面向对象设计中的一个原则是低耦合高内聚,保持每个对象的相对独立性。
那么, 我应该将我的应用,设计成一个类吗? 也就是说在这一个类中, 要管理: Device, IVR和一个Socket服务器吗?
 
Unit Interface;

TIA = Class
pulic
procedure A; virtual; abstract;
end;
TIB = Class
pulic
procedure B; virtual; abstract;
end;
TIC = Class
pulic
procedure C; virtual; abstract;
end;

Unit A
use Interface;
TA = Class(TIA)
private
FB: TIB; <<-- 这里就可以使用TIB接口类中定义的功能了。
FC: TIC; <<-- 具体使用时用TC对象赋值。
public
procedure A; override;
end;
 
不需要啊,你只要把这几个类的偶合度降低就可以了。
 
to nicai_wgl:
ok, 明白了, thx.

to all:
如果还有朋友有兴趣可以继续讨论, 我稍后结帖.
 
接受答案了.
 
后退
顶部