首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网页制作-> Discuz!专栏
代码重构——之获得封装性delphi编码实例_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
代码重构——之获得封装性DELPHI编码实例
 
代码重构是获得结构良好的方法,通过重构,我们在保持功能不变的情况下,改善代码的质量,提高代码的复用程度。下面是一个获得改善代码质量和获得封装性的一个具体的例子。(例子使用DELPHI)
代码功能:
       给数据集设(TClientDataSet)置过滤器,用户可以在一个TComboBox中选择要过滤的字段,然后在一个Tedit框中输入要过滤的值。如图一:
最常见的做法就是在TComboBox的Items属性中硬码写入我们数据集中的字段名称,然后在代码中加入一大堆case或者if语句在判断用户选择的字段来给数据集设置过滤器。
……
      case ComboBox1.ItemIndex of
0:
             ClientDataSet.Filtered := False;
        ClientDataSet.Filter := F_CODE = + Edit2.Text + ;
              ClientDataSet.Filtered := True;
1:
             ClientDataSet.Filtered := False;
        ClientDataSet.Filter := F_CHINESE_NAME = + Edit2.Text + ;
              ClientDataSet.Filtered := True;
……       
end;                
或者用
….…
       if ComboBox1.Text = 物料编码 then
    begin
              ClientDataSet.Filtered := False;
        ClientDataSet.Filter := F_CODE = + Edit2.Text + ;
              ClientDataSet.Filtered := True;
end
else if ComboBox1.Text = 名称 then
begin
ClientDataSet.Filtered := False;
        ClientDataSet.Filter := F_CHINESE_NAME = + Edit2.Text + ;
              ClientDataSet.Filtered := True;
 
end
……
这样的代码通过硬码同样也实现了这个给数据集设置过滤器的功能,满足了需求,但是上面这段代码是不灵活的。如果数据集的字段很多就要求编码人员一个一个字段录入在Items中,而且在写case必须核对好顺序,不然设置的过滤器就是错误的也就很容易由开发人员引入BUG。用if语句时也一样维护一个大量的if同样是痛苦的,而且不支持需求变化,当用户要求改变数据集字段的中文显示名称时必须也要记住更改TComboBox. Items中的硬码数据,如果一旦忘记就会引入BUG。
 
于是我在第一次重构中,尝试动态的加载TComboBox. Items中的数据,同时为了实现加载后用户选择时实现对照。我在这个查询FORM中加了一个 私有FFields: array[0..20, 0..2] of string; 字段来保存数据集中的字段信息数据。同时实现了一个加载数据的过程:
 
procedure TFrmSPARealStorageQuery.GetQueryFields;
var
  i, iFieldsCount: Integer;
begin
  iFieldsCount := 0;
  with DBGride1.DataSource.DataSet do
  begin
    for i := 0 to Fields.Count - 1 do
      if Fields[i].Visible then
      begin
        FFields[iFieldsCount, 0] := Fields[i].FieldName;
        FFields[iFieldsCount, 1] := Fields[i].DisplayLabel;
        Inc(iFieldsCount);
      end;
    ComboBox1.Items.Clear;
    for i := 0 to iFieldsCount - 1 do
      ComboBox1.Items.Add(FFields[i, 1]);
  end;
end;
 
这样就实现了在运行时动态加载字段信息。这样我的过滤器设置就变成了这样的。
 
if ComboBox1.Text <> then
begin
ClientDataSet.Filtered := False;
    ClientDataSet.Filter := FFields[ComboBox1.ItemIndex, 0] +   + Edit2.Text + ;
       ClientDataSet.Filtered := True;
end;
 
本方法无疑增加了代码的灵活性,同时增加了代码的复用度,因为代码很好的隔离了变化的数据。因此只要在另一个也是要实现这种的功能的FORM中增加私有字段FFields: array[0..20, 0..2] of string 和使用上面的动态加载数据集字段过程,就可以说方便的实现了重用。但是这种重用并不是很好的,因为我们没有实现很好的封装性。导致在你的程序中到处散落有重复的代码(你常常会通过COPY来获得这个函数的重用,因为上面的代码是没有好的封装性)。如果有一天你要修改数据装载函数你就必须到处去找那里拷贝了该函数——你也得修改散落在其他地方的代码。于是我进行了再一次的重构,并对代码进行了进一步的封装。
代码如下:
unit uDataSetFieldsInfo;
// Description:单元包括 TDataSetFieldsInfo 类,该类封装了获得数据集子段信息。
// 并提供了在combobox列表显示字段显示信息和获得对应子段名称的方法接口
// Created : wuchhao
// Date : 2003.5
 
interface
uses Classes, DBClient, StdCtrls;
type
  TDataSetFieldsInfo = class
  private
    FFieldsList: TStrings;
  public
    constructor Create;
    destructor Destroy; override;
    procedure GetDataSetFields(Source: TClientDataSet);
    procedure ShowFieldsInfo(Target: TComboBox);
    function GetFieldsNameByDisplayLabel(DisplayLabel: string): string;
  end;
 
implementation
 
{ TDataSetFieldsInfo }
constructor TDataSetFieldsInfo.Create;
begin
  FFieldsList := TStringList.Create;
end;
 
destructor TDataSetFieldsInfo.Destroy;
begin
  FFieldsList.Free;
  inherited;
end;
 
procedure TDataSetFieldsInfo.GetDataSetFields(Source: TClientDataSet);
var
  i: Integer;
begin
  FFieldsList.Clear;
  with Source do
  begin
    for i := 0 to Fields.Count - 1 do
      if Fields[i].Visible then
      begin
        FFieldsList.Add(Fields[i].DisplayLabel);
        FFieldsList.Add(Fields[i].FieldName);
      end;
  end;
end;
 
function TDataSetFieldsInfo.GetFieldsNameByDisplayLabel(
  DisplayLabel: string): string;
var
  index: Integer;
begin
  Result := ;
  index := FFieldsList.IndexOf(DisplayLabel);
  if index <> -1 then
    Result := FFieldsList.Strings[index+1]  ;
end;
 
procedure TDataSetFieldsInfo.ShowFieldsInfo(Target: TComboBox);
var
  i: Integer;
begin
  Target.Items.Clear;
  i:=0;
  while i <  FFieldsList.Count do
  begin
    Target.Items.Add(FFieldsList.Strings[i]);
    i:= i+ 2;
  end;
end;
end.
 
单元uDataSetFieldsInfo 封装了与实现本文所述功能相关的数据和方法,把它们封装在一个类里面,从而实现了面向对象设计里面的 Open - Close 原则。类变成了一个黑盒,于是就可方便的重用(black-box reuse),而不必担心代码的重复。同时因为封装了与功能相关的信息,类的职责定义明确(单职责),并有了足够合适的粒度和好的封装性。TdataSetFieldsInfo 很好的把组合框与变化的数据隔离开来,最终提高了代码的复用程度,同时减少了FORM类的职责和 magic number硬编码的量。下面是新的代码:
首先在FORM中声明TdataSetFieldsInfo类的一个引用。
……
在FORM创建的时候调用:
FFieldsInfo := TDataSetFieldsInfo.Create;
FFieldsInfo.GetDataSetFields(cdMaster);
FFieldsInfo.ShowFieldsInfo(ComboBox1);
这时候我的过滤器设置就变成了:
if ComboBox1.Text <> then
begin
ClientDataSet.Filtered := False;
    ClientDataSet.Filter := FFieldsInfo.GetFieldsNameByDisplayLabel(ComboBox1.Text) +   + Edit2.Text + ;
       ClientDataSet.Filtered := True;
end;
 
通过调用FfieldsInfo对象的接口过程来获得对应的子段名称。
 
本文是一个重构代码的简单例子,我想上面我实现的这个类还可以有很多种写法和更好的算法。这里只是提供一种关于重构代码的思路,为提高我们的编写代码质量和它的可维护性、扩展性,探讨OOD编程方式上的思路。

文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·Eclipse + Lomboz + Tomcat JSP 开发配置-JSP教程,Jsp/Servlet
·利用Java调用可执行命令实例-JSP教程,Java技巧及代码
·彻底搞定JSP在线人数-JSP教程,Jsp/Servlet
·数据库操作类实现(C#,SqlClient)-.NET教程,C#语言
·在C#中实现打印功能(C#中PrintDialog,PrintDocument的使用)-.NET教程,C#语言
·结合PHP使用HTML表单(2)-PHP教程,PHP应用
·Java中利用JMF编写摄像头拍照程序-JSP教程,Java技巧及代码
·解析.Net框架下的XML编程技术-.NET教程,XML应用
·ASP.net Logion用户登陆验证代码-.NET教程,Asp.Net开发
·Java中精确计算的一个类用BigDecimal-JSP教程,Java技巧及代码
最新文章
·超越adsense:另类方法赚取巨额收益_网赚技巧
·google adwords优化技巧_网赚技巧
·自己误点adsense广告不用再通知google了_网赚技巧
·用fireworks滤镜轻松制作可爱gif动画_fireworks教程
·网站赚钱:google关键词广告创建的十二高招_站长心得
·提升网站使用性 打造实用性网站_站长心得
·最快速登录到google的10点主要经验_google推广
·制作主页的四十个技巧1_站长心得
·利用rss和gmail备份你的blog_站长心得
·seo终极方法_seo网站优化
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭