荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: oopilix (优雅的), 信区: Visual
标  题: [zz]Delphi 惯用法 from大富翁[fr]
发信站: 荔园晨风BBS站 (Sat May 31 23:04:16 2003), 站内信件


作者: joyyuan97
{ No. 1 }
//创建模式窗体的句子
class procedure TMyForm.RunForm(AObj1, AObj2: TObject);
var
vForm: TMyForm;
begin
vForm := TMyForm.Create(Application);
with vForm do
Try
 InitForm(AObj1, AObj2);
 ShowModal;
Finally
 Free;
end;
end;
(*说明:
通过class声明的函数,类似与VC中的静态函数;使用语句:TMyForm.RunForm(vObj1,
vObj2);
其他具体的,参考:Delphi 帮助中的,class 类说明。
强调这个惯用法,就是为了:
1、如果此窗体在多处被使用,那么可以保证统一都调用此段代码;
2、如果功能上有所修改,比如:根据ShowModal的返回值不同进行处理,那么只修改此
函数就行了。
3、程序封装性好,易于维护和工作交接。

*)


{ No. 2 }
//窗体工具栏按钮事件的响应
procedure TMyForm.RunOperate(ATag: Integer);
begin
 Case ATag of
 1: MyButton.Color := clRed;
 2: MyButton.Color := clGreen;
 3: MyButton.Color := clBlack;
 end;
end;

procedure TMyForm.ToolBtnClick(Sender: TObject);
begin
 RunOperate(TControl(Sender).Tag);
end;

//如果你在某下拉菜单中,也需要执行类似功能则
procedure TMyForm.MenuItemClick(Sender: TObject);
begin
 RunOperate(TMenuItem(Sender).Tag);
end;

(*说明:
1、结构清晰
2、相关的信息集中,比较容易查错、修改和维护
3、提高程序的适应、扩展能力;比如现在要求不在工具栏按钮中实现,而要求在不同
按钮中实现,则修改容易。
建议:每个分类后面只跟一行或不多的几行代码,如果代码比较多,使用过程函数替代。
比较有意思的是,我经常如下写:
Case btnMyButton.Visible of
{ 显示 } True: ...
{不显示} False: ...
end;
*)



{ No. 3 }
//对于列表等的读取使用事件指针的方式
type
 TDataSetEvent = procedure (DataSet: TDataSet; AIndex, ACount: Integer) of
Object;
//从 TADOQuery派生而来的类
procedure TMyADOQuery.EnumRecord(AWhereStr: String; APro: TDataSetEvent);
begin
 Close;
 SQL.Clear;
 SQL.Add('Select * From Table1');
 if AWhereStr <> '' then
   SQL.Add('Where ' + AWhereStr);
 Open;
 While Not Eof do
 begin
   if Assigned(APro) then APro(Self, RecNo, RecordCount);
   Next;
 end;
 Close;
end;

(*说明:
此方法来自与Window中,枚举当前所有子窗体的API函数,EnumChildWindow
1、原则:尽量将数据读取与数据显示、数据处理等分离;如:MVC等都是此目的。
2、程序扩展性增强,如果您原来希望在列表中显示或处理某列信息,后来改为用
ComboBox,则在修改程序时,不在阅读数据读取部分,只需要修改信息显示等即可。
又比如,现在要求您在读取记录时,用进度条显示读取进度等。
*)



{ No. 4 }
//使用数组

{ 在惯用法 No.2 中,实现了如下的内容
procedure TMyForm.RunOperate(ATag: Integer);
begin
Case ATag of
1: MyButton.Color := clRed;
2: MyButton.Color := clGreen;
3: MyButton.Color := clBlack;
end;
end;
}
//那么用数组方式实现,则就比较理想了
procedure TMyForm.RunOperate(ATag: Integer);
const
 MyButtonColorMax := 3;
 MyButtonColor: array [1..MyButtonColorMax] of TColor = (clRed, clGreen,
 clBlack);
begin
Case ATag of
1..MyButtonColorMax:  MyButton.Color := MyButtonColor[ATag];
101:....
end;
end;

(*说明:
对于数组方式使用,只要注意数组的上限或下限使用常量来实现,然后在以后使用中都尽
量使用此常量进行数组循环读取就行了。
*)

{ No. 5 }
//如何让一个窗体中,尽量减少公共函数的定义;
{
比如:要实现一个当前窗体控件的属性列表窗体,当需要刷新属性窗体;改变某属性值;
添加新的属性等;会有很多需要交互的信息。如果我们使用类公共函数,则需要定义很
多的公共函数。同时,如果需要进行窗体类型转换,转换为目标窗体类型才可以使用
公共函数。所以,会遇到两个
单元需要互相包含的情况 }
//解决方案:
TfrmMyForm = class(TForm)
 FfrmProperty: TForm;
end;

...
 FfrmProperty := TfrmProperty.MyCreate(Application, Self);
...

//当需要刷新属性窗体时
 FfrmProperty.Perform(WD_REFRESHPROPERTYLIST, 0, 0);

TfrmProperty = class(TForm)
private
 FMyForm: TForm; procedure WDREFRESHPROPERTYLIST(var Message: TMessage);
message WD_REFRESHPROPERTYLIST;
public
 constructor MyCreate(Owner: TComponent; AForm: TForm);
end;

constructor TfrmProperty.MyCreate(Owner: TComponent; AForm: TForm);
begin
 inherited Create(Owner);
 FMyForm := AForm;
end;

(* 对于使用消息的方式,可以减少窗体公共函数的定义。同时,提高程序的可扩充
性。如果,使用他的窗体替代时,则可以比较轻松的转换,因为如果最多也就是您
的窗体,对当前的消息没有进行处理而已 *)

{ No. 6 }

//项目:要求你对一个数据集支持多种输出显示方式

...例子,以后给出

(* 说明:
1、“多种输出方式”,说明输出方式在今后的应用中可能会经常扩充,因此要在程序
设计时考虑到输出方式的易扩充性。
2、参考VCL中,控件注册(RegisterComponents)的机制,可以发现VCL中大量的使用到
了注册机制;其中比较经典的就是控件属性编辑器的注册了。
*)

{ No. 6 }

//如果您做的是一个二次开发平台的程序,则必须涉及到产品版本控制和项目版本控制
问题
//通常使用预定义的方式控制

//语句比较简单了就是:
{$DEFINE JOYYUAN97}
{$IFDEF JOYYUAN97} {ELSE} {ENDIF}
{$UNDEF JOYYUAN97}

(*说明:
1、将预定义划分在多个单独的文件中。
2、在每个单元的最前头但在Unit 后,使用{$I ...} 将文件包含(Include)进当前单元
3、根据预定义情况控制当前单元所能包含的单元文件
4、尽量单独划分一个针对项目的预定义文件在包含所有预定义文件后,包含此文件,
则在此文件中,可以针对项目的需要,将取消部分预定义{$UNDEF JOYYUAN97}
*)

{ No. 8 }

//我经常的认为减少单元的包含,是做公共单元的第一步,所以在如何尽量减少单元包含
//也就是如何减少程序单元的耦合性上,应多下工夫。

{ 情景描述:
TMyFormManager: 窗体管理类
TMyForm:数据窗体基础类
TMyFormAccess:窗体信息保存和读取类。将窗体信息保存到数据库或其他什么类型的结
构中分析:
1、窗体基础类(TMyForm) 和 窗体管理类(TMyFormManager)需要在一个单元 uManagers中
实现。
2、窗体具体实现类(TMyImageForm)单元 fMyImange 需要包含单元uManagers,进行窗体
继承,和窗体管理。
3、窗体数据读取类(TMyFormAccess)单元 uMyAccess 需要包含单元uManagers和单元
fMyImange
问题:
 如果我希望实现窗体保存,那么应该在窗体的某个按钮事件中实现。则涉及到窗体单元
需要包含窗体数据访问类单元,而如果放在窗体基础类中,则单元uManager又必须包含单

uMyAccess。
 当数据访问,即数据存储格式会根据要求而改变并要求可扩充时,则单元包含必定是一个
隐患。
解决办法:使用函数指针变量。
1、在单元uManagers中定义一个,保存数据信息的函数指针变量。
2、在应用程序初始化的时候给这个函数指针变量赋值。
3、在需要保存窗体信息时,判断如果指针不为空,则执行函数保存窗体信息。

}



--
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 61.144.235.39]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店