前面框架初始化过程及通讯路径建立过程可能没有写得很清楚,这里先将本框架的mvc的通讯机制先贴出,欢迎各位高手提出宝贵意见,写得不好别扔鸡蛋砖头就行; 1、主窗体创建时,创建控制器实例;代码如下: PagesController := TS2AdapterDataPagesController.Create(Self, GetGlobalSystemObject); 创建后,控制器即接管了用户所有的时间,并对所有的事件进行转发; {实现接口IS2DataAdapterController} procedure Append(O: TS2Object); virtual; procedure Cancel(O: TS2Object); virtual; procedure Delete(O: TS2Object); virtual; procedure Modify(O: TS2Object); virtual; procedure Update(O: TS2Object); virtual; procedure First(); virtual; procedure Last(); virtual; procedure Next(); virtual; procedure Prior(); virtual; 这里用到了适配器模式(Adapter);通过IS2DataAdapterController统一接口,实现对view视图的转发;见单元:unit S2.Controller.TS2AdapterDataPagesController;比如增加按钮(增加按钮在TS2AdapterDataPagesController)事件转发代码如下: procedure TS2AdapterDataPagesController.Append(O: TS2Object); begin if FindActiveView and FindActiveDataAdapterController then begin _ActiveDataAdapterController.Append(O); end; end; //代码说明:查找活动view( FindActiveView)及返回适当的适配器 //(FindActiveDataAdapterController);活动视图就是通过下面第二步创建出来 //的,第二步说明; 而_ActiveDataAdapterController申明的类型就是接口:IS2DataAdapterController;而返回的是视图的接口,代码如下: function TS2AdapterDataPagesController.FindActiveDataAdapterController: Boolean; begin Result := True; if (_ActiveView is TS2AdapterDataItemsView) then _ActiveDataAdapterController := _ActiveView as TS2AdapterDataItemsView else if (_ActiveView is TS2AdapterDataItemView) then _ActiveDataAdapterController := _ActiveView as TS2AdapterDataItemView else Result := False; end; //这样有控制器的事件就转发到具体的每个视图上了,当前活动视图;
2、每个视图(比如基础资料维护窗口等,从TS2AdapterDataGridView、TS2AdapterDataItemView、TS2AdapterDataItemsView继承下来)要通过控制器来创建,具体代码如下:PagesController.AppendView(TEmployeeGridView);具体创建过程这里就不详说了,在第一帖已经说过;控制器就是根据当前的活动视图来查找到对应的视图并返回接口; 视图类TS2AdapterDataItemsView对接口IS2DataAdapterController的实现将代码进行转发,转发到了IS2DataAdapter适配器,发代码如下: procedure TS2AdapterDataItemsView.Append(O: TS2Object); begin GetDataModel.GetDataAdapter.Append; end; TS2AdapterDataItemView也实现了接口IS2DataAdapterController,不过框架里的代码是空的,我想过程也是一样的; 视图类将转发来得事件转发给客户端数据模块并,GetDataModel代码如下: function TS2DataView.GetDataModel: TS2ClientDataModel; var Model: TS2Model; begin Model := GetModel; Result := GetModel as TS2ClientDataModel; end; 客户端数据模块继续转发给数据库模块接口IS2DataAdapter,通过此接口将事件继续转发; 3、客户端数据模块是通过视图初始化时通过服务器端数据库模块注册时创建并设置的; SetModel((GetSystemObject.GetServerDataModelFactory as TS2ServerDataModelFactory).GetModel(ServerDataModelClass) as TS2Model); 4、客户端数据模块将事件转发给服务器端数据模块代码如下: Append等一些事件不进行转发,保存事件进行转发,转发代码如下: procedure TS2AdapterClientDataModel.Save; begin if not IsModified then Exit; PrepareSave; if not ValidateData then raise S2DataSuncertaintyException.Create(ClassName, 'Save'); BeforeSave(nil); try ConsolidationUpdateLog; GetServerDataModel.Save; except on E: Exception do raise S2DataAdapterException.Create(ClassName, 'Save', ParseDataAdapterError(E)); end; AfterSave(nil); end;
procedure TS2AdapterClientDataModel.ConsolidationUpdateLog; begin _ClientDataSet.DisableControls; try _ClientDataSet.StatusFilter := [usInserted]; if _ClientDataSet.RecordCount > 0 then GetServerDataModel.Append(_ClientDataSet);
_ClientDataSet.StatusFilter := [usModified]; if _ClientDataSet.RecordCount > 0 then GetServerDataModel.Modify(_ClientDataSet);
_ClientDataSet.StatusFilter := [usDeleted]; if _ClientDataSet.RecordCount > 0 then GetServerDataModel.Delete(_ClientDataSet); finally _ClientDataSet.StatusFilter := []; _ClientDataSet.EnableControls; end; end; 至此,整个由用户操作触发的事件最后转发到服务器端数据模块TS2ServerDataModel,并完成对数据库的读写操作; 通讯简图如下: