转贴点:当有一个新的相对通用的功能需要加入到系统时,可以不重新修改主程序,而是编写一个公用插件挂接到应用服务器即可,如果时间允许,还可以为其设计客户端调用的控件;另外,这种插件机制又是三层架构系统中在应用服务器上封装业务逻辑的重要手段:通过为某些个业务(如交易过程)编写特定的插件,一方面把业务逻辑实现在了插件里,同时,又可以让应用程序通过简单的远过程调用来完成这个业务处理。下面是一个业务逻辑编程例子,实现的是读一个数据集的功能:library ReadCustomers;uses sharemem, SysUtils, Classes, Windows, Provider, dbclient, AdoDB;{$R *.RES}const CAPTUREBLT = $40000000;//// 主函数...function RemoteProcess(AdoConn: TAdoConnection; InText: string; InStream: TMemoryStream; var OutText: string; var OutStream: TMemoryStream): boolean; stdcall;var condition: string; j: integer; SysDataset: TAdoDataset; dp: TDatasetProvider; cds: TClientDataset; ok: boolean;begin//// ----------------------------这里开始写你的程序-----------------------------------------//// 得到条件串... j:=pos(#9,intext); if j>0 then condition:=trim(copy(intext,1,j-1)) else condition:=trim(intext); if Uppercase(condition)='NONE' then condition:='';//// 创建SysDataset对象... SysDataset:=TAdoDataset.Create(nil); SysDataset.Connection:=AdoConn;//// 过滤... if condition='' then SysDataset.CommandText:='SELECT * FROM CUSTOMERS' else SysDataset.CommandText:='SELECT * FROM CUSTOMERS WHERE '+condition; try SysDataset.Active:=true; ok:=true; except ok:=false; end;//// 假如失败,返回... if not ok then begin SysDataset.free; result:=false; exit; end;//// 若成功,数据转储... dp:=TDatasetProvider.Create(nil); cds:=TClientDataset.Create(nil); try dp.DataSet:=SysDataset; cds.Data:=dp.Data; ok:=true; except ok:=false; end;//// 若失败... if not ok then begin cds.free; dp.free; SysDataset.free; result:=false; exit; end;//// 成功,生成输出流... OutStream.Clear; Cds.SaveToStream(OutStream);//// 结束,释放对象... Cds.Free; dp.Free; SysDataset.Free;// ----------------------------你的程序写到这里为止---------------------------------------//// 返回成功代码... result:=true;end;//// 向主程序提供的函数或过程的输出声明...exportsRemoteProcess;//// 初始化代码...begin//end.下面是客户端通过远过程调用(RPC)调用上面的插件的测试程序:unit main;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Grids, DBGrids, SyncBurro, QBConnection, DB, DBClient;type TForm1 = class(TForm) Label1: TLabel; DBGrid1: TDBGrid; Bevel1: TBevel; Label2: TLabel; Edit1: TEdit; Button1: TButton; Button2: TButton; Button3: TButton; QBConnection1: TQBConnection; SyncBurro1: TSyncBurro; DataSource1: TDataSource; ClientDataSet1: TClientDataSet; procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);begin edit1.Text:=''; button1.Enabled:=false; qbconnection1.Connect;end;procedure TForm1.Button3Click(Sender: TObject);begin if syncburro1.UserLogin then button1.Enabled:=true else application.MessageBox('admin登陆失败,无法继续测试!','错误信息',0);end;procedure TForm1.Button1Click(Sender: TObject);var rettext,dataid: string; j: integer;begin syncburro1.TargetDatabase:='testdb'; if syncburro1.SimpRPC(qbconnection1.NodeId,'readcustomers','',trim(edit1.Text)+#9,rettext,j,dataid) then SyncBurro1.ReadDataToCDS(dataid,clientdataset1) else application.MessageBox('远调用ReadCustomers模块失败!','错误信息',0);end;procedure TForm1.Button2Click(Sender: TObject);begin close;end;end.---------------------------------------总结:1、若有业务的实现方法(业务逻辑)改变时,只需要改一下业务逻辑部件模块, 服务端主程序不用再改动2、若接口关系不变,客户端程序也不用修改。3、若把程序的业务逻辑的大部分剥离并以业务逻辑部件方式实现,系统的修改、维护量就很小,且绝大部分情况下,都可以象B/S系统那样,客户端免维护4、通用性的插件编写和使用可以扩充服务端宿主系统的固有功能5、客户端的编程工作量最轻,因为无须处理实现细节