三层中关于接口转换,业务封装 ( 积分: 100 )

  • 主题发起人 主题发起人 martinwang
  • 开始时间 开始时间
to 迷糊:
IDispatch接口付给一个olevariant再传递到客户端调用,这个可以的我做过
==========================================
像你说的,服务器端定义一个函数,参数类型改为OleVariant
服务器端:
var iTest:ITest1
procedure TMyTest.Test(var a: OleVariant);
begin
iTest:=TDataModule3.Create(nil);
a:= iTest ;//到这里都OK
end;
//这里报错,怀疑是接口生存期问题????
客户端:
var a:OleVariant;
begin
SocketConnection1.AppServer.Test(a);
报“一般性拒绝访问错误”!!跟了一下到服务器,注释!!
不知道是何原因,帮忙:)谢谢!!!:)
 
xdjm们都来帮忙啊:)
 
在<Delphi 5开发人员指南>第三十章有一个很好的例子,客户端没有一个SQL语句,你可以看一下.
张兄的观点:
每增加一个业务从数据库端进行业务逻辑的实现,即一个或多个存储过程的总体,客户端调用一个方法完成业务的实际!!以前做两层的时候,数据库是MSSQL时基本采用这种方式,用户在修改业务逻辑的时候,只需要在数据库端把对应的存储过程改动一下即可,用的也是比较的爽!!
做业务层的目的是为了使业务逻辑与界面层的剥离,而且易于测试和维护.我再倾向于把业务层写成相关的类来.
 
to pathnet:
<Delphi 5开发人员指南>这本书现在不是很好找,能提供电子版下载URL吗??
呵,其实两层与三层的区别就在于数据库连接池等方面的优势,而其封装业务方面其实和两层应该是一样的!看过几个数据库封装成类的东东,把一些数据的操作做成接口,或是抽象类,然后子类进行实现或是继承!始终没有找到一个经典的三层的例子,所以请大家帮忙!!!!:)
 
以前别人说可以O/R mapping理论把表里的字段映身成类,找过许多这方面的资料,大部分都是关于java的,在delphi里的很少,不知道大家有没有这方面的例子啊,呵:)
 
都来啊!!!:)
 
<Delphi 5开发人员指南>在www.2ccc.com(delphi盒子)有下载。
数据库应用主要就是增删查,如果只是简单的增删查的话,可能二层应该很好,如果应用到决策支持的话,还是三层的好,这样业务逻辑封装在中间层,如果业务逻辑改变,只要改中间层即可,这样系统维护成本较低。
虽然知道一些三层概念,很多问题还不是很清楚。学习ing!
 
martinwang,
关于服务接口和实现继承的方法,在你提出这个问题后,我作了研究
现已经有一套成熟方案在工程中使用.有兴趣的话,可以在这里继续讨论
 
看看李维的那三本书,能有收获的,以及刘艺的《面向对象编程》
 
比较感兴趣,张大侠先给粗略地说说吧,不懂的再问
 
帮你顶一下
 
我们编写Com+数据服务模块的一般方法是,
新建一个ActiveX Library,
新建一个Transaction DataModule
然后,在这个工程的类型库编辑器中增加自定义的接口方法,
实现这些接口方法.
一旦我们写了很多这类服务,会发现,我们总是重复类似的服务接口,同时也重复编写
类似的实现代码,自然会想到继承。
首先,我们考虑到接口的继承,非常不幸,在类型库编辑器中,从接口的Parent Interface下拉列表中,除了系统预定义的标准接口可以继承外,我们似乎找不到自己的接口基类。
另一方面,实现单元,对象继承自TMtsDataModule,单元的Initilization部分使用了对象工厂创建自动化对象,这种方式,让我们很难用传统方法使用实现继承。
针对实现继承的需求,我们建立的服务基类,不要继承自Transactional DataModule,而是使用Transactional Object,配合一个普通的DataModule,来实现类似Transactional DataModule的功能,这样,普通DataModule的实现代码就可以被继承了。
当然,这种方法牺牲了IAppServer预定义的As_*这类接口,事实上,我从来不在客户程序中调用这些接口。
理解了上述基本思路后,对于熟悉Com+数据服务模块编写方法者,从以下文档可以理解我的基本设计思想:
本基类提供子母表datamodule的基础框架和接口框架
被继承的数据模块:
dMasterDetailBase.pas
被继承的接口声明:
mtsMsterDetailBase_TLB
继承后的mts实现单元代码模板:
MasterDetailImpl.pas
下面是使用这个基类来继承子母表服务的基本方法:
1、准备工作:
为了使用这个基类,做好以下准备:
regsvr32 mtsMsterDetailBase.dll -----使这个接口可以被类型库编辑器继承
2、继承的基本步骤:
2.1 建立服务工程文件:
新建一个Active Libruay
保存为 mtsXXX
在工程中加入单元:dMasterDetailBase.pas,mtsMsterDetailBase_TLB
dMasterDetailBase.TdmMasterDetail是准备被继承的datamodule
工程属性设置(最好设为默认):
Packages:钩选Build with Run Time Package ,仅包含 vcl;rtl;vclx
编译路径: ../../发行包/server
2.2 继承数据模块(TdmMasterDetail):
file/new/other
找到本工程页,选择dmMasterDetail,按ok继承它
这时,一个datamodule被创建,把它保存为dXXX.pas
datamodule对象命名为dmXXX
这时,我们就可以修改这个datamodule中各个query的sql语句,使它访问新的模块的树据库对象
2.3继承Com接口:
为了不重复写类型库中的接口方法声明,可以继承IMasterDetail接口
继承IMasterDetail接口的步骤:
file/new/other/ActiveX/Transactional Object
CoClass Name: XXX
支持事务
把这个文件命名为XXXImpl.pas
在类型库编辑器中,点击根节点,打开Uses页
右键,Show All Type libruaries
找到mtsMasterDetailBase,打勾(如果找不到,是你没有注册mtsMsterDetailBase.dll)
右键,Show Selected
在类型库编辑器中点击IXXX节点,在Attributes页,将Parent Interface改为IMasterDetail
刷新类型库
这样,IMasterDetail接口的所有方法都被继承了
关闭类型库编辑器
2.4 实现服务接口:
下面,来实现XXXImpl.pas中的对象方法,基本上是抄MasterDetailImpl.pas中的样本代码
为了方便抄写代码,可以在IDE中打开MasterDetailImpl.pas,但不要把它加到工程中
首先,在XXXImpl.pas中的interface部分的uses中加入dMasterDetailBase
在对象 Txxx的私有部分加入以下声明:
private
FDM:TdmMasterDetail;

在公有部分加入以下声明:
public
//声明下列方法并实现他们
procedure Initialize;
override;
destructor Destroy;override;
实现:
procedure TXXX.Initialize中
FDM 使用你继承后的datamodule来创建,即,
FDM:=TMasterDetailBase.Create(nil);
改为:FDM:=TdmXXX.Create(nil);
为了上面的代码能够调试通过,你还要在实现部分uses dXXX
其他实现代码照抄MasterDetailImpl.pas中的相应部分
至此,一个继承的masterdetail服务模型就出来了
2.5 细化数据模块的逻辑
这个工作主要是在Query组件中编写各个SQL代码
为了方便调试DataModule中的细节,可以新建一个测试exe文件,加入dMasterDetailBase和dXXX.pas
在执行文件中调试数据模块就比较容易了
2.6 编译mts服务
数据模块细化并调试成功后,简单打开mt工程,编译它就可以了
其他说明:
如果在新的服务中需要扩充接口,可以在类型库中自行扩充
 
强~
学习~
 
收藏! 敬礼~~
 
后退
顶部