delphi三层架构

这是我多年前在深圳工作时写的,现在都迁移来CSDN上,免的丢失了。


      三层架构指的是界面,业务逻辑和数据存储分离,不是指物理上是否分离。

      这样做的好处是层次分明,维护好做,系统资源也好分布式处理。

      数据库层哪就不说了,用MSSQL、Orcale随你了,就是数据服务层

      业务逻辑的话要分析清楚,就是中间层界面,也叫客户端。这里就是得到数据和显示数据的部分了,不做其它处理。但是数据有效性分析最好放在界面层,以充分利用客户端的性能。不然的话业务逻辑层的负担太大也会形成瓶劲。

      数据库的建立不说了。


三层体系的建立

一 数据库层的建立

      使用sqlserver或orale建立数据库。


二 中间层的建立

      一般将中间层分为二个部分,数据部分和逻辑部分。

     数据部分就是使用原始的查询,一个ado连接,多个成对出现的adq和dsp。ado连接最后选使用文件连接,以便以后可以在客户端自由决定连接哪个数据库而不需要改程序。

逻辑部分跟客户端一样,使用DCom来连接到数据部分,然后使用cds连接到DCOM并指明数据提供器dsp.然后再增加相应的函数来处理数据。事务一般取自动维护的,这样函数开始事务自动开始,我们只需要维护事务回滚setAbout,和事务完成setcomplete.在中间层服务器中不要添加需要人主动干预的动作,比如对话框之类。因为中间层服务器和数据库一样是长时间不间断运行的,也没有谁会呆在中间层服务器前专门处理这些问题。

例:delphi7 sqlserver2000,win32环境

在delphi中建立一个多层项,选Translation Data Moudle

取个名testTran,线程模式Threadling Model选Aparment,等会再改它。

事务模式Translation model取 需要一个事务requires a Translation

点OK就建立了一个中间层。

然后得改一改线程模式由tmApartment改成tmNeutral.(在initialization的 TComponentFactory.Create里改参数。)

再就可以添加数据控件进行处理了。


三 客户端的建立

     客户端的建立,取数据直接用DCOM连接,cds取。如果是逻辑业务的话就用 DCOM.appserver.函数来处理。

     主从结构在这里有一个小技巧。如果将主从结构放在中间层的话,主表第一次取数据时会遍历主表,从表也会跟着查一次,如果主表条数很多,会造成用时很长。如查将主从结构放在客户端的话,主表第一次取数从表不会跟着走一次,哪样速度就快很多。但是如果主表条目数很少,而且在取得数据后经常变动的话,还是将主从结构放在中间层较好,这样查询到的数据是暂存起来的,这样得到数据就会很快。



附:线程模式 

1.Single:单线程,只有一个Rmd线程,所有客户端只能顺序地得到服务。 
2.Apartment:服务程序可以同时有多个Rmd线程,但每个Rmd线程只能服务以单线程模式运行。 
3.Free:没有线程限制的模式,没见用过。 
4.Both:介于Apartment和Free之间的一种线程模式,没见用过。 
5.Neutral:仅对Com+有效,可以使多个客户端同时以多线程模式应用服务器,建议使用,但注意全局变量的保护问题。


更详细的一些说明在下面:


    Delphi7 COM/DCOM线程模式

    建立多层会让用户选择一些模式。

    如果是远程数据模块RDM则会有选实例属性(Instancing)和线程模式(Threading Model)

    如果是事务数据模块TDM则会让选线程模式(Threading Model)和事务模式(Transaction Model)

    一 实例属性(Instancing)

        1.Internal:服务程序内部创建实例,客户端的申请服务行为无法创建实例 
        2.Single Instance:单实例模式,服务程序只能有一个Rmd实例,不同的客户端只能顺序申请服务或启动多个服务程序实例来获取服务 
        3.Multiple Instance:多实例模式,一个服务程序实例可以创建多个Rmd实例,不同客户端可以应用不同的Rmd实例

    二线程模式(Threading Model)

        1.Single:单线程,只有一个Rmd线程,所有客户端只能顺序地得到服务。只有一个线程服务任何客户端的要求。 
        2.Apartment:,服务程序可以同时有多个Rmd线程,但每个Rmd线程只能服务以单线程模式运行。允许COM服务器线程拥有多个相同的Apartment在不同的服务器线程中执行,如些一来就可以同时服务许多的客户端。但是在每一个Apartment中只有一个单一的线程可以执行这个Apartment中任何的COM对象。由于在COM服务器中可能有数个线程同时在执行,所以每一个线程必须小心保护全域变量的存取。 
        3.Free:没有线程限制的模式。允许客户端应用程序同时存取COM服务器之中的任何COM对象。少用 
        4.Both:同时支持Apartmetn和Free的线程模型。这意谓着在这个COM服务器中可以有多个不同使用不同线程模型的COM对象。此外Both线程模型也保证当它通过接口回叫客户端的应用程序时,所有的回叫是依序的,而且会回叫到正确的客户端线程。少用。 
        5.Neutral:仅对Com+有效,可以使多个客户端同时以多线程模式应用服务器,建议使用,但注意全局变量的保护问题。

    三事务模式(Transaction Model)

        1 requires a Transaction

        需要事务。这种MTS/COM+对象在执行时一定需要事务context的存在。如果客户端已经建立了事务context,哪么这种对象就会使用这个事务context。如果客户端没有建立事务context的话,哪么MTS/COM+便会为这种对象建立事务context。通常,这种对象都是因为需要事务处理数据的修改才会需要一个事务context.所以程序员在撰写数据对象、事务对象或协调对象时可以选择建立这种对象。

        2 requires a new Transaction

        需要新的事务。在被激活时一定需要MTS/COM+为它建立一个新的事务context,而不能使用客户端已经建立的事务context。这种MTS/COM+对象一定是在它建立的事务context中执行。而绝对不会在客户端的事务context中执行。由于这种MTS/COM+对象需要建立额外的事务context,所以会造成系统额外的负荷,而且它的事务不受客户端事务context的控制。因此用它要经过仔细的考虑。

        3 supports Transactions

        支持事务。可以在客户端的事务context中执行,也可以没有事务context的状况下执行。开发功能对象、控制对象、或协调对象可以选用。

        4 Does not supports Transactions

        不支持事务。这种对象属于以前MTS/COM+尚未出现之前的COM对象。这种对象不会在MTS/COM+的事务Context中执行,所以即使客户端激活一个事务context,这种对象也不会在客户端的事务context中执行。由于这种对象完全不理会MTS/COM+对于企业对象的管理,所以建议不会建立。

        5 Ignores Transactions

        忽略事务。




  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
随便说说最近项目中的三层架构吧。讲点实际的东西。我最讨厌空讲道理。网上讲道理的太多了,不喜欢举例子。 大多数文章中都或多或少的讲到了三层架构。表示层,业务层,数据层。又把业务层再细分,分为外观服务层,主业务服务,及数据库库服务层。 今天主要讨论一下业务层吧。举个最简单的例子。客户端获取数据。 业务层要与表示层尽量解藕, 我的方法是:首先我们在中间层TLB_中定义一个接口 IBusinessService, 定义一个方法。getvoList,我要得到一个VO的列表, VO即ValueObject, 例如:TValueObject= class(TPersistent) private b_insertFlag :Boolean; b_updateFlag :Boolean; b_deleteFlag :Boolean; d_rowVersion :double; procedure setInsertFlag(pInsertFlag :Boolean); function getInsertFlag: Boolean; procedure setUpdateFlag(pUpdateFlag :Boolean); function getUpdateFlag: Boolean; procedure setDeleteFlag(pDeleteFlag :Boolean); function getDeleteFlag: Boolean; procedure setRowVersion(pRowVersion :double); function getRowVersion:double; protected function GetOLEData: OleVariant; virtual; procedure SetOLEData(const Value: OleVariant); virtual; published property bInsertFlag: Boolean read getInsertFlag write setInsertFlag; property bUpdateFlag: Boolean read getUpdateFlag write setUpdateFlag; property bDeleteFlag: Boolean read getDeleteFlag write setDeleteFlag; property dRowVersion: double read getRowVersion write setRowVersion; property POLEData:OleVariant read GetOLEData write SetOLEData; end;TUserVO = class(TValueObject) private id: string; name: string; password: string; 。。。。。。。。。。 VO的列表:TValueObjectList = Class(TObjectList) private ValueObject: TValueObject; ClassName: TClass; procedure setClassName(pTmpClsName :TClass); function getClassName: TClass; procedure setValueObject(pTmpVO :TValueObject); function getValueObject: TValueObject; protected function GetOLEData: OleVariant; virtual; procedure SetOLEData(const Value: OleVariant); virtual; published function AddItem(index: integer; AObject: TObject ):Integer; virtual; function GetItem(index, itemid: integer ): TObject; virtual; function CountItem:Integer; virtual; public constructor Create; virtual; destructor Destroy; override; procedure AfterConstruction; override; property PClassName: TClass read getClassName write setClassName; property POLEData: Ole

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值