CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  数据库相关

面向对象的数据库开发?

楼主cjianwen(空前)2006-06-03 21:20:16 在 Delphi / 数据库相关 提问

我现在和朋友一起开发一个小项目,把每个表结构都定义为一个类,然后每条记录都为一个对象,然后读写都对该对象进行操作,这样的开发方法好吗?  
   
  感觉有点烦索,但又好像用起来比较方便,到底我们这种方法是不是在走弯路呢?迷茫。。。。  
   
  高人指点下! 问题点数:100、回复次数:55Top

1 楼liangqingzhi(老之)回复于 2006-06-03 21:25:21 得分 10

汗,没必要这样吧Top

2 楼cjianwen(空前)回复于 2006-06-03 21:32:17 得分 0

哦,谢谢大侠的关注,没必要这样那我们就是在浪费时间了 ̄ ̄ ̄?  
   
  汗。。。。我花了一天的时间来写了一个通用的基类,然后在上面进行扩展,发现要写的代码也不多 ̄ ̄ ̄,但不知道我这样一层套一层的会不会影响速度!!!Top

3 楼lee576()回复于 2006-06-03 21:41:01 得分 10

东西先搞出来完成主要功能再说,先给客户一个交待,优化修改的工作后期再进行,像画画一样先画个轮廓再画细节和局部Top

4 楼whbo(王红波(年轻人,要有所作为))回复于 2006-06-03 21:41:17 得分 10

那是浪费时间,你们的操作,本身就封装好了的  
  表,数据集,都已经在delphi中可直接操作的。Top

5 楼wudi_1982(向伴水学习|胃出血,住院中)回复于 2006-06-03 23:44:34 得分 10

如果是当作对于面向对象知识的学习,不错。。是一种积累。但如果是实际开发,那就没有必要了,就是浪费。Top

6 楼FCU(吃羊肉串居然上火,郁闷!)回复于 2006-06-04 00:14:51 得分 0

实在是没有这个必要。Top

7 楼Rail100(杀神之狙)(能忘掉结果,未能忘记遇上)回复于 2006-06-04 00:16:48 得分 0

开发时比较费力,维护很方便,扩展也容易。实际开发这个很重要,因为细节很容易变化。Top

8 楼78hgdong(赤脚)回复于 2006-06-04 08:40:10 得分 10

无形中你已使用了面向对象了,我看功能不是很复杂,不用每个表结构都定义为一个类吧....Top

9 楼cncharles(旺仔)回复于 2006-06-04 08:51:50 得分 20

类的继承的层次不要太深,   派生用接口取代(多层)继承比较好.Top

10 楼Hank(星星农场)回复于 2006-06-04 14:14:29 得分 0

如果是20年前你这么干绝对是最好的办法,因为你这本身是再做数据库,只是没有通用引擎而已。  
   
  现在你这么干绝对是浪费时间,除非是你的东西要求极其保密而且数据量很小!  
   
  20年前你最多看到dBase和FoxBase,现在你能看到的数据库当时统统没有或者根本就见不到Top

11 楼GARNETT2183(KingWolves (http://kevin-lu.blogspot.com))回复于 2006-06-04 14:20:03 得分 10

建意多看看模式设计,这样会提高的效率...Top

12 楼GARNETT2183(KingWolves (http://kevin-lu.blogspot.com))回复于 2006-06-04 14:25:36 得分 10

看了模式设计,才会体会面向对象设计的强大和扩展性,灵活性.这对你以后维护和扩展有非常大的帮助...Top

13 楼cjianwen(空前)回复于 2006-06-04 17:32:17 得分 0

呵呵,模式设计,没看过,不知道讲什么,有机会看看!!!  
   
  明天我把代码贴上来,我只是自己私下在写着玩,还不知道老大会不会用我写的这个基类呢!  
   
  也有可能漏洞百出,大家帮指点下!Top

14 楼zzzl(不拉拉链)回复于 2006-06-04 18:11:04 得分 10

设计模式在数据库操作中不灵了Top

15 楼paladinwang(paladin)回复于 2006-06-05 00:07:40 得分 0

这种设计在bs的工程中比较常见,应该说如果仅仅为了功能的话是没必要,如果你的工程很简单也没必要,但是如果你的工程有些复杂,或者为了以后维护的方便,这样做绝对是个好主意。说实话看到有人说设计模式在数据库操作的应用中不灵实在是让人感到伤心。Top

16 楼GARNETT2183(KingWolves (http://kevin-lu.blogspot.com))回复于 2006-06-05 09:37:14 得分 0

设计模式在数据库操作中不灵了  
  /////////////  
  不灵,你有没有体验过它所带来的效率?Top

17 楼lzf1010(深宇)回复于 2006-06-05 10:30:04 得分 0

在数据库开发中分为两中模式的,一种是dataset,另一种是对象的,也就是楼主现在想用的这种方式  
  这两种方式各有优点,并且一直在争论到底哪一种更好  
  delphi中对dataset的支持非常好,用delphi的人也对该模式运用十分熟练,如果你在delphi版问这个问题,绝大部分人都不会支持你的做法的,如果你去java或者.net,支持你的人可能会多些  
  如果你是基于VCL架构来开发的话,我还是建议你使用dataset,如果你是基于delphi.net,那么我建议你使用ECO,其实你要做的,ECO已经做得很好了,没必要重复前人的工作  
  我个人觉得,面向对象的数据库开发方式是以后的趋势,dataset的方式只适合(中)小型应用Top

18 楼getit911(Windows转Linux中)回复于 2006-06-05 10:40:55 得分 0

用ECO就解决了,不过小项目,实在是画蛇添足,没必要。Top

19 楼getit911(Windows转Linux中)回复于 2006-06-05 10:41:59 得分 0

像楼主这种干法比较像JAVA那套,JAVA最大优势就是简单问题复杂话,呵呵。Top

20 楼Mrkang(谁比我菜我不愿意)回复于 2006-06-05 10:58:12 得分 0

我现在和朋友一起开发一个小项目,把每个表结构都定义为一个类,然后每条记录都为一个对象,然后读写都对该对象进行操作,这样的开发方法好吗?  
  ================  
  还没真正理解面向对象啊,面向对象是双刃剑,用好了无敌与天下,但是想用好了很难..  
  业务基类没必要那么复杂的,把通用的操作和数据放在基类里,其他的都可以通过他继承的.  
  在继承类里实现要求不是很好吗?Top

21 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-05 11:05:28 得分 0

很好,这样的系统一般比较好维护,我有这方面的经历,给你几点建议:  
  1,基类最好是方法的集合,而不是数据的集合;  
  2,类之间的责任要明确;  
  3,不要为模式而模式;Top

22 楼cjianwen(空前)回复于 2006-06-05 13:22:05 得分 0

基类如下:  
   
  unit   Unit4;  
   
  interface  
   
  uses  
      SysUtils,   Classes,   DB,   ADODB;  
   
  const   MAX_LINE   =   '20';  
  type  
        TMyField   =   Class(TObject)  
      private  
          FIsChange:   Boolean;  
          FFieldName:   string;  
          FFieldValue:   string;  
          FDataType:   TFieldType;  
          procedure   SetFieldValue(const   Value:   string);  
          public  
            property   IsChange   :   Boolean   read   FIsChange;         //是否改变,只读  
            property   FieldValue:string   read   FFieldValue   write   SetFieldValue;   //字段值  
            property   FieldName:string   read   FFieldName;       //字段名   ,只读  
            property   DataType:TFieldType   read   FDataType;   //字段的数据类型,只读  
            constructor   Create(aFieldName:string;aFieldType:TFieldType;aValue:string='');  
            destructor   Destroy;override;  
          end;  
  type  
          TCommonInfo   =   class(TObject)         //该类可以作为其它类的基类进行扩展  
      private  
          FFieldCount:   integer;  
          UpdateFields:string;               //要修改的字值和值串   ,保存到数据库时用  
          FFields:array   of   TMyField;  
          FQry:TAdoQuery;  
          FTableName:   String;  
          FKeyFields:   string;  
          function   GetFieldType(aFieldName:String):TFieldType;   overload;  
          function   GetFieldType(Index:integer):TFieldType;     overload;  
          function   IsValidOp(aop:String):Boolean;     //是否为有效的操作符  
          function   GetMainCondition:string;         //根据主键获得条件,获取   where   后面的条件子句  
          function   UniteField(aField:TMyField;aand:boolean=true;aValue:String=''):String;     //连接字段值和条件,中间的参数代表是否加and运算符  
          function   UniteStr(aFieldName:string;aFieldValue:string;aand:boolean=true):String;//联接含有字段串的字段,加引号   ,最后一个参数代表是否加   and  
          function   UniteInt(aFieldName:string;aFieldValue:string;aand:boolean=true):String;//接接不加引号的字段   ,最后一个参数代表是否加   and  
          function   IsValidFieldIndex(index:integer):boolean;     //检查索引是否有效  
          procedure   InitField;             //初始化字段数组  
          function   IsValidFieldName(aFieldName:string)   :   Boolean;       //是否为有效的字段名  
          function   IsKeyField(aFieldName:string):boolean;     //字段名是否为主键  
          function   SelectSQL(aSQL:string):Boolean;         //执行返回结果的SQL,并给相应的域赋值  
      protected  
          property   TableName:String   read   FTableName;       //只读,表名  
          function   GetInfoWithCondition(aFieldName,aOp,aValue:   string):Boolean;overload;   //根据条件获取信息     三个参数分别为:操作数,操作符,值  
          function   GetInfoWithCondition(aCondition:String):boolean;overload;     //根据条件取数据  
          function   IsChanged:Boolean;                                 //判断所有的字段值是否改变  
          function   GetFieldValue(aFieldName:string)   :   String;   overload;   //根据字段名获取字段值  
          function   getFieldValue(Index:integer):string;     overload;         //根据索引获取字段值  
          function   SetFieldValue(aFieldName:String;aValue:String):boolean;   overload;   //根据字段名设置字段名  
          function   SetFieldValue(Index:integer;aValue:String):Boolean;overload;       //根据索引设置字段值  
          function   GetFieldName(Index:integer):String;       //根据索引获取字段名  
      public  
            function   PerformSQL(aSql:string):boolean;     //值行不返回结果的SQL  
            property   FieldCount:integer   read   FFieldCount;     //字段总数  
            property   KeyFields:string   read   FKeyFields;       //主键字段  
            function   SaveToDataBase():Boolean;                         //保存当前数据到数据库  
            constructor   Create(aTableName:String;Constr:String;aKeyFields:String);   //参数分别为:表名,连接字符串,主键的的集合,如:ID;ANAME;  
            Destructor   Destroy;   override;  
            end;  
   
  implementation  
   
  {   TMyField   }  
   
  constructor   TMyField.Create(aFieldName:   string;aFieldType:   TFieldType;aValue:String='');  
  begin  
  self.FFieldName   :=   aFieldName;  
  //showmessage(self.FFieldName);  
  self.FisChange   :=   false;  
  self.FDataType   :=   aFieldType;  
  self.FFieldValue   :=   aValue;  
  inherited   create;  
  end;  
   
  destructor   TMyField.Destroy;  
  begin  
      inherited;  
  end;  
   
  procedure   TMyField.SetFieldValue(const   Value:   string);  
  begin  
  if   FFieldValue   <>   Value   then  
      begin  
      FFieldValue   :=   Value;  
      FIsChange   :=   true;  
  //     showMessage('change'+Value);  
      end;  
  end;  
   
  {   TCommonInfo   }  
   
  constructor   TCommonInfo.Create(aTableName,   Constr:   String;   aKeyFields:String);  
  begin  
  FTableName   :=   aTableName;  
  FQry   :=   TADOQuery.Create(nil);  
  FQry.ConnectionString   :=   Constr;  
  FKeyFields   :=   aKeyFields;  
  InitField;  
  inherited   create;  
  end;  
   
  destructor   TCommonInfo.Destroy;  
  var  
  i:integer;  
  begin  
      FQry.Free;  
      for   i   :=   0   to   high(FFIelds)   do  
          begin  
              if   assigned(FFIelds[i])   then  
                FFields[i].Free;  
          end;  
      inherited;  
  end;  
   
  function   TCommonInfo.GetFieldValue(aFieldName:   string):   String;  
  var  
  i:integer;  
  begin  
    result   :=   '';  
  if   not   IsValidFIeldName(aFieldName)   then   exit;  
    for   i   :=   0   to   FFieldCount-1   do  
      if   UpperCase(FFields[i].FieldName)   =   UpperCase(aFieldName)   then  
          begin  
              result   :=   FFields[i].FieldValue;  
              break;  
          end;  
  end;  
   
  function   TCommonInfo.GetFieldValue(Index:   integer):   string;  
  begin  
  result   :=   '';  
  if   (Index   <   0)   or   (Index   >=   FieldCount)   then  
      raise   Exception.Create('Field   Index   out   of   bounds!');  
    result   :=   FFields[Index].FieldValue;  
  end;  
   
  function   TCommonInfo.GetFieldName(Index:   integer):   String;  
  begin  
  result   :=   '';  
  if   not   IsValidFieldIndex(Index)   then   exit;  
  result   :=   FFIelds[Index].FieldName;  
  end;  
   
  procedure   TCommonInfo.InitField;  
  var  
  i:integer;  
  begin  
      with   FQry   do  
          begin  
              close;  
              sql.Text   :=   Format('select   Top   %s   *   from   %s   where   1<>2',[MAX_LINE,FTableName]);  
              open;  
          end;  
    FFieldCount:=   FQry.FieldCount;  
    SetLength(FFields,FFieldCount);  
    for   i:=0   to   FFieldCount-1   do  
        begin  
            FFields[i]   :=   TMyField.Create(Fqry.Fields[i].FieldName,Fqry.Fields[i].DataType);  
        end;  
  end;  
   
  function   TCommonInfo.IsChanged:   Boolean;  
  var  
  i:integer;  
  begin  
  result   :=   false;  
  UpdateFields   :=   '';  
      for   i:=0   to   FFieldCount-1   do  
          begin  
            if   self.FFields[i].IsChange   =   true   then  
                  begin  
                      Result   :=   true;  
                      if   Length(UpdateFields)   <=   0   then  
                          UpdateFields   :=   UpdateFields   +   UniteField(FFields[i],false)       //将改变的字段和值连起来,保存到数据库的时候用  
                      else   UpdateFields   :=   UpdateFields   +   '   ,   '   +   UniteField(FFields[i],false);   //false   代表不加   and连接符  
                  end  
            end;  
  end;Top

23 楼cjianwen(空前)回复于 2006-06-05 13:23:09 得分 0

function   TCommonInfo.SetFieldValue(aFieldName,   aValue:   String):   boolean;  
  var  
  i:integer;  
  begin  
    result   :=   false;  
  if   not   IsValidFIeldName(aFieldName)   then   begin   {showmessage('set   value   exit');}exit;end;  
    for   i   :=   0   to   FFIeldCount-1   do  
        begin  
          if   UpperCase(FFields[i].FieldName)   =   UpperCase(aFieldName)   then  
                begin  
                  FFIelds[i].FieldValue   :=   aValue;  
                  break;  
                end;  
          end;  
  result   :=   true;  
  end;  
   
  function   TCommonInfo.SaveToDataBase:   Boolean;  
  var  
  i:integer;  
  s:string;  
  begin  
  result   :=   false;  
  if   IsChanged   then  
      s   :=   'Update   '   +   FTableName   +   '   set   '   +   UpdateFields   +   'Where   1=1   '   +   GetMainCondition  
  else   begin   {showmessage('not   change!');}exit;end;  
    //   showmessage(s);  
  result   :=   self.PerformSQL(s);  
  end;  
   
  function   TCommonInfo.SetFieldValue(Index:   integer;   aValue:   String):   Boolean;  
  begin  
  result   :=   false;  
  if   not   IsValidFieldIndex(Index)   then   exit;  
    FFIelds[Index].FieldValue   :=   aValue;  
  result   :=   true;  
  end;  
   
   
  function   TCommonInfo.IsValidFieldIndex(index:integer):   boolean;  
  begin  
  result   :=   false;  
      if   (Index   <   0)   or   (Index   >=   FieldCount)   then  
        begin  
          raise   Exception.Create('Field   Index   out   of   bounds!');  
          exit;  
        end;  
  result   :=   true;  
  end;  
   
  function   TCommonInfo.IsKeyField(aFieldName:string):   boolean;  
  begin  
  result   :=   pos(UpperCase(aFieldName),UpperCase(FKeyFields))   >   0;  
  //showmessage(aFieldName+':'+FKeyFIelds+':'+booltostr(result,true));  
  end;  
   
  function   TCommonInfo.IsValidFieldName(aFieldName:   string):   Boolean;  
  var  
  i:integer;  
  begin  
  result   :=   true;  
    for   i   :=   0   to   FFIeldCount-1   do  
        begin  
          if   UpperCase(FFIelds[i].FieldName)   =   UpperCase(aFieldName)   then  
              begin  
                  exit;  
              end;  
          end;  
  result   :=   false;  
  end;  
   
  function   TCommonInfo.UniteInt(aFieldName,   aFieldValue:   string;aand:boolean=true):   String;  
  begin  
  if   aand   then  
  result   :=   Format('   and   %s   =   %s   ',[aFieldName,aFieldValue])  
  else   result   :=   Format('   %s   =   %s   ',[aFieldName,aFieldValue]);  
  //showmessage('UniteInt   result:'+result);  
  end;  
   
  function   TCommonInfo.UniteStr(aFieldName,   aFieldValue:   string;aand:boolean=true):   String;  
  begin  
  if   aand   then  
  result   :=   Format('   and   %s   =   ''%s''   ',[aFieldName,aFieldValue])  
  else   result   :=   Format('   %s   =   ''%s''   ',[aFieldName,aFieldValue]);  
  end;  
   
  function   TCommonInfo.GetMainCondition:   string;  
  var  
  i:integer;  
  begin  
  result   :=   '';  
  //showmessage('getmaincondition');   这句执行到了,IsKeyField这句有总题  
  for   i   :=   0   to   FFieldCount   -1   do  
        begin  
              if   IsKeyField(FFields[i].FieldName)   then  
                  begin  
                  //     showmessage(FFIelds[i].FieldName);  
                  result   :=   result   +   UniteField(FFIelds[i]);  
                  end;  
        end;  
  end;  
   
  function   TCommonInfo.UniteField(aField:   TMyField;aand:boolean=true;aValue:string=''):   String;  
  begin  
  result   :=   '';  
  if   aField.DataType   =   ftstring   then  
        begin  
        if   aValue   <>''   then  
              result   :=   UniteStr(aField.FieldName,aValue,aand)  
        else  
        result   :=   UniteStr(aField.FieldName,aField.FieldValue,aand)  
        end  
  else  
          begin  
          if   aValue   <>''   then  
              result   :=   UniteInt(aField.FieldName,aValue,aand)  
          else  
          result   :=   UniteInt(aField.FieldName,aField.FieldValue,aand);  
          end;  
  end;  
   
  function   TCommonInfo.PerformSQL(aSql:   string):   boolean;  
  var  
  i:integer;  
  begin  
  result   :=   false;  
      try  
        with   FQry   do  
            begin  
                close;  
                sql.Text   :=   aSql;  
                ExecSQL;  
            end;  
      except  
          result   :=   false;  
          exit;  
      end;  
  result   :=   true;  
  end;  
   
  function   TCommonInfo.GetInfoWithCondition(aFieldName:string;aOp:string;aValue:   string):   Boolean;  
  var  
  i:integer;  
  s:string;  
  begin  
  result   :=   false;  
  if   not   IsValidOp(aop)     then   begin     exit;end;  
  if   not   IsValidFieldName(aFieldName)   then   begin   exit;end;  
  if   GetFieldType(aFieldName)   =   ftString   then  
  s   :=Format('select   top   %s     *   From     %s   where   %s   %s   ''%s''',[MAX_LINE,FTableName,aFieldName,aop,aValue])  
  else     s   :=Format('select   top   %s     *   From     %s   where   %s   %s   %s',[MAX_LINE,FTableName,aFieldName,aop,aValue]);  
  result   :=   self.SelectSQL(s)  
  end;  
   
   
  function   TCommonInfo.IsValidOp(aop:   String):   Boolean;  
  begin  
  result   :=   (aop   =   '<')   or   (aop   =   '>')   or   (aop   =   '>=')   or   (aop   =   '<=')   or   (aop   =   '<>')   or   (aop   =   '=');  
  end;  
   
  function   TCommonInfo.GetFieldType(aFieldName:   String):   TFieldType;  
  var  
  i:integer;  
  begin  
  if   not   IsValidFieldName(aFieldName)   then   exit;  
        for   i   :=0   to   FFIeldCount   -1   do  
              begin  
                if   UpperCase(FFIelds[i].FieldName)   =   UpperCase(aFieldName)   then  
                    begin  
                    result   :=   FFields[i].DataType;  
                    break  
                    end;  
              end  
  end;  
   
  function   TCommonInfo.GetFieldType(Index:   integer):TFieldType;  
  begin  
  if   not   IsValidFieldIndex(Index)   then   exit;  
    result   :=   FFields[Index].DataType;  
  end;  
   
  function   TCommonInfo.GetInfoWithCondition(aCondition:   String):   boolean;  
  var  
  s:String;  
  begin  
  result   :=   false;  
  s   :=Format('select   top   %s     *   From     %s   where   %s',[MAX_LINE,FTableName,aCondition]);  
  if   SelectSQL(s)   then  
  result   :=   true;  
  end;  
   
  function   TCommonInfo.SelectSQL(aSQL:   string):   Boolean;  
  var  
  i:integer;  
  begin  
  result   :=   true;  
  try  
  with   FQry   do  
        begin  
          close;  
            sql.Text   :=   aSQL;  
            open  
          end;  
    for   i   :=   0   to   FFIeldCount   -1   do  
                  begin  
                      FreeAndNil(FFields[i]);  
                      if   FQry.IsEmpty   then  
                          FFIelds[i]   :=   TMyField.Create(FQry.Fields[i].FieldName,FQry.Fields[i].DataType,'')  
                      else  
                      FFields[i]   :=   TMyField.Create(FQry.Fields[i].FieldName,FQry.Fields[i].DataType,Fqry.Fields[i].AsString);  
  //                     showmessage(FFIelds[i].FieldValue);  
                  end  
  except  
    result   :=   false;  
  end;  
  end;  
   
  end.Top

24 楼cjianwen(空前)回复于 2006-06-05 13:25:20 得分 0

下面是一个在上面的基础上扩展后的类:  
   
   
  unit   Unit5;  
   
  interface  
   
  uses  
  SysUtils,   Classes,unit4;  
   
  Type  
    TStuInfo   =   class(TCommonInfo)  
      private  
          procedure   SetAddr(const   Value:   string);  
          procedure   SetAge(const   Value:   string);  
          procedure   SetID(const   Value:   String);  
          procedure   SetRemarks(const   Value:   String);  
          procedure   SetSex(const   Value:   string);  
          procedure   SetSname(const   Value:   String);  
          procedure   SetTel(const   Value:   String);  
          function   GetID:   String;  
          function   GetAddr:   string;  
          function   GetAge:   string;  
          function   GetRemarks:   String;  
          function   GetSex:   string;  
          function   GetSname:   String;  
          function   GetTel:   String;  
            public  
            property   ID:String   read   GetID   write   SetID;  
            property   Sname:String   read   GetSname   write   SetSname;  
            property   Sex:string   read   GetSex   write   SetSex;  
            property   Age:string   read   GetAge   write   SetAge;  
            property   Tel:String   read   GetTel   write   SetTel;  
            property   Addr:string   read   GetAddr   write   SetAddr;  
            property   Remarks:String   read   GetRemarks   write   SetRemarks;  
            Constructor   Create(TableName,ConnStr,KeyFields:string);  
            Destructor   Destroy;   override;  
            function   GetInfoWithId(aid:String):boolean;  
            function   GetInfoWithSname(aSname:String):Boolean;  
            function   GetInfoWithSex(aSex:String):Boolean;  
            function   GetInfoWithTel(aTel:String):Boolean;  
            function   GetInfoWithAge(aAge:String):Boolean;  
            function   GetInfoWithAddr(aAddr:String):Boolean;  
            function   GetInfoWithRemarks(aRemarks:String):boolean;  
            end;  
   
  implementation  
   
  {   TStuInfo   }  
   
  constructor   TStuInfo.Create(TableName,   ConnStr,   KeyFields:   string);  
  begin  
  inherited;  
  end;  
   
  destructor   TStuInfo.Destroy;  
  begin  
      inherited;  
  end;  
   
  function   TStuInfo.GetAddr:   string;  
  begin  
  result   :=   GetFieldValue('addr');  
  end;  
   
  function   TStuInfo.GetAge:   string;  
  begin  
  result   :=   GetFieldValue('age');  
  end;  
   
  function   TStuInfo.GetID:   String;  
  begin  
  result   :=   GetFieldValue('id');  
  end;  
   
  function   TStuInfo.GetInfoWithAddr(aAddr:   String):   Boolean;  
  begin  
  result   :=   GetInfoWithCondition('Addr','=',aAddr);  
  end;  
   
  function   TStuInfo.GetInfoWithAge(aAge:   String):   Boolean;  
  begin  
  result   :=   GetInfoWithCondition('Age','=',aAge);  
  end;  
   
  function   TStuInfo.GetInfoWithId(aid:   String):   boolean;  
  begin  
  result   :=   GetInfoWithCondition('Id','=',aId);  
  end;  
   
  function   TStuInfo.GetInfoWithRemarks(aRemarks:   String):   boolean;  
  begin  
  result   :=   GetInfoWithCondition('Remarks','=',aRemarks);  
  end;  
   
  function   TStuInfo.GetInfoWithSex(aSex:   String):   Boolean;  
  begin  
  result   :=   GetInfoWithCondition('Sex','=',aSex);  
  end;  
   
  function   TStuInfo.GetInfoWithSname(aSname:   String):   Boolean;  
  begin  
  result   :=   GetInfoWithCondition('Sname','=',aSname);  
  end;  
   
  function   TStuInfo.GetInfoWithTel(aTel:   String):   Boolean;  
  begin  
  result   :=   GetInfoWithCondition('Tel','=',aTel);  
  end;  
   
  function   TStuInfo.GetRemarks:   String;  
  begin  
  result   :=   GetFieldValue('remarks');  
  end;  
   
  function   TStuInfo.GetSex:   string;  
  begin  
  result   :=   GetFieldValue('sex');  
  end;  
   
  function   TStuInfo.GetSname:   String;  
  begin  
  result   :=   GetFieldValue('Sname');  
  end;  
   
  function   TStuInfo.GetTel:   String;  
  begin  
  result   :=   GetFieldValue('tel');  
  end;  
   
  procedure   TStuInfo.SetAddr(const   Value:   string);  
  begin  
  SetFieldValue('addr',Value);  
  end;  
   
  procedure   TStuInfo.SetAge(const   Value:   string);  
  begin  
  SetFieldValue('Age',Value);  
  end;  
   
  procedure   TStuInfo.SetID(const   Value:   String);  
  begin  
  SetFieldValue('id',Value);  
  end;  
   
  procedure   TStuInfo.SetRemarks(const   Value:   String);  
  begin  
  SetFieldValue('Remarks',Value);  
  end;  
   
  procedure   TStuInfo.SetSex(const   Value:   string);  
  begin  
  SetFieldValue('sex',Value);  
  end;  
   
  procedure   TStuInfo.SetSname(const   Value:   String);  
  begin  
  SetFieldValue('sname',Value);  
  end;  
   
  procedure   TStuInfo.SetTel(const   Value:   String);  
  begin  
  SetFieldValue('Tel',Value);  
  end;  
   
  end.  
   
   
  Top

25 楼foxyy8888(C4 E3 CC AB D3 D0 B2 C5 C1 CB A3 A1)回复于 2006-06-05 15:31:52 得分 0

没什么大的必要。Top

26 楼sunxianyu(找工作)回复于 2006-06-05 15:35:44 得分 0

*_*,  
  我什么时候能写出来~~~~顶了Top

27 楼xjqxpj008()回复于 2006-06-05 15:46:43 得分 0

狂汗~~~我是菜鸟,喜欢自己编东西。  
  看见长的程序就烦,呵呵。  
  不过~~~顶你了Top

28 楼hawksoft(明月清风)回复于 2006-06-05 17:03:21 得分 0

用不着脱裤子放屁吧。  
  Top

29 楼cjianwen(空前)回复于 2006-06-05 17:44:16 得分 0

晕呀,怎么就没人支持一下呢!!!!  
   
  我怎么感觉这样维护起来比较方便~~!  
   
  只需改动小的细节就行了,用不着满屏找代码!!!Top

30 楼GARNETT2183(KingWolves (http://kevin-lu.blogspot.com))回复于 2006-06-05 18:08:43 得分 0

我支持啊。。。Top

31 楼ln521(*逃课小王子*)回复于 2006-06-05 19:59:40 得分 0

看时间是不是充足了  
  Top

32 楼Hank(星星农场)回复于 2006-06-05 20:16:29 得分 0

晕死,原来楼主开头所说的和代码的东西完全不是一回事啊。  
   
  我现在和朋友一起开发一个小项目,把每个表结构都定义为一个类,然后每条记录都为一个对象,然后读写都对该对象进行操作,这样的开发方法好吗?  
   
  >>>>>>>>>>>>>>>>  
   
  实际上不是那么回事,譬如一个字段名称改了或者数据库加了一个字段,你还不是要修改基类,比修改代码还罗嗦。  
   
  最好看看ADO的原生资料及Delphi对ADO的引用后再说,就他们都保证不了这些。Top

33 楼cjianwen(空前)回复于 2006-06-06 08:13:04 得分 0

TO   星星农场,请看下面的几行代码:  
   
   
  with   FQry   do  
          begin  
              close;  
              sql.Text   :=   Format('select   Top   %s   *   from   %s   where   1<>2',[MAX_LINE,FTableName]);  
              open;  
          end;  
    FFieldCount:=   FQry.FieldCount;  
    SetLength(FFields,FFieldCount);  
    for   i:=0   to   FFieldCount-1   do  
        begin  
            FFields[i]   :=   TMyField.Create(Fqry.Fields[i].FieldName,Fqry.Fields[i].DataType);  
        end;  
   
  如果数据库的结构改了这个通用的基类的结构也会跟着改的,然后在派生类中添加一个属性和读写方法就可以了!  
   
  当然这个类并没有考虑到Blob字段!Top

34 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-06 08:13:22 得分 0

譬如一个字段名称改了或者数据库加了一个字段,你还不是要修改基类  
   
   
  ------------------------------------------------------------------------------  
  按楼主的这种写法,是不需要修改基类的,只需要修改子类,  
  按照这样的开发方式做出来的系统要好维护得多,  
  只有你自己用这样的方式开发过系统,你才会承认的。Top

35 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-06 08:16:41 得分 0

当然这个类并没有考虑到Blob字段!  
   
  ---------------------------------------------------------------  
  频繁地使用Blob字段的系统性能会好吗?  
   
  Blob字段这样的数据应该放在数据库里?Top

36 楼cncharles(旺仔)回复于 2006-06-06 08:27:57 得分 0

靠,   我还以你是开发一个类似数据库的东西.   简单的看了些代码  
  才知道是脱裤子放屁,   根本没有必要做得这么复杂.Top

37 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-06 08:33:32 得分 0

楼主,看到这么多批评的回复,是预料之中的事。。。  
  不要难过,你是正确的!  
  起码你不会让你的继任者在复杂的代码堆里迷失方向!  
  软件的后期维护,难啊!!!Top

38 楼lzf1010(深宇)回复于 2006-06-06 10:00:06 得分 0

呵呵,虽然楼主的方向是正确的,但是处理方法上我觉得还不太成熟Top

39 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-06 10:05:29 得分 0

楼上说的有道理,楼主需要学习和改进,慢慢来吧,就怕方向都错了!Top

40 楼VisualLion(狮子)回复于 2006-06-06 17:47:19 得分 0

支持楼主,应该有限的使用ORMTop

41 楼cjianwen(空前)回复于 2006-06-06 18:00:25 得分 0

噢,好象真的没用!唉,浪费时间,这两天倒把多态搞明白点了,真晕!!!!Top

42 楼badboy19800808(我是大飞猪他爹!!!)回复于 2006-06-07 08:01:02 得分 0

不是没有用,只是火候未到而已!  
  http://blog.csdn.net/badboy19800808/archive/2006/04/28/695610.aspxTop

43 楼jkx01whg(爱迪01)回复于 2006-06-07 09:31:37 得分 0

dingTop

44 楼gaolin(木木)回复于 2006-06-12 15:38:15 得分 0

楼主,看到这么多批评的回复,是预料之中的事。。。  
  不要难过,你是正确的!  
  起码你不会让你的继任者在复杂的代码堆里迷失方向!  
  软件的后期维护,难啊!!!  
  Top

45 楼cangwu_lee(橙子)回复于 2006-06-12 16:31:28 得分 0

路过Top

46 楼skypeople(飞飞)回复于 2006-06-12 16:45:10 得分 0

尽信书不如无书,如果你是初学者,强列建议你让OOP见鬼去吧,跟着感觉写就行了;  
  唉 OOP的宣传,真是误导了不少人;Top

47 楼huitouren519(细节决定成败)回复于 2006-06-16 09:52:38 得分 0

学习Top

48 楼wizardqi(男巫)回复于 2006-06-16 10:56:14 得分 0

呵呵,如果你是在高三层开发,把业务与数据分开的话,这个设计还算比较适应。  
  当然关键是要针对项目的生命力,如果该项目将来会有较长时间的应用而且数据结构变化不是很大使用这种设计还是必要的。  
  至于你所说的类的层次结构会不会降低效率,那是肯定的单对于现代计算机来说可以忽略不计。  
  而如果这个项目只是短期的比如用户固定,而且投资又不是特别高的话这样做就没必要了。  
  Top

49 楼jixinming(小明)回复于 2006-06-17 17:20:50 得分 0

好象不太好的,慢Top

50 楼XXSingle(心无了然)回复于 2006-06-17 18:02:16 得分 0

支持,方向是对的,继续走下去.........,前期虽然烦琐,但是后期维护方便;  
  Top

51 楼marry2000()回复于 2006-06-17 19:03:35 得分 0

楼主,我先前公司的产品架构就是把数据库的信息都转化成类,对象的。  
  多层的结构,客户端没有如adoquery,clientdataset之类的东西,只有业务类,对象,及显示控件(没有数据感知控件)。  
  客户端有个业务的基类,它最主要是利用RTTI方法,读取后代类的实例,将它的数据信息传到中间层和接收中间层的数据把它转化客户端业务类的信息。  
  中间层也有个基类,也是利用RTTI将后代的实例数据转化成一组sql命令,由它进行对数据库的操作,同样从数据库得到数据转成对象的信息,传给客户端。  
  在客户端写好了n多的方法,比如将对象的所有信息显示到界面等等。。。  
  经过了这样的封装,并不是像有些人讲的为了后期维护方便,最重要的是提高代码复用,加速以后项目开发速度。公司做了n个项目了(基本都是大几十万的单),都是同一个架构(当然基类也在不断维护扩充)。还有很多好处,比如客户端的灵活性等等,不一一多说。当然也有缺点,效率肯定不如直接用dataset高等。。。  
  要提醒楼主的是,这样的基类编写不是一两天搞定的,需要积累,实践,沉淀。(公司的底层基类是经过几年才逐渐成熟的)  
  如果只是为了一个,两个项目而去弄这个,那没必要。Top

52 楼47522341(睡到8:30)回复于 2006-06-17 19:08:53 得分 0

相当于给本来就很臃肿的公司结构再加一层中间领导层。  
   
  从效率来讲,最理想的公司当然是一个老板,其余人全部是works;  
  在老板忙活不过来的时候可以考虑加中间管理层。这样的话,相对高效的做法也应该是完全n叉树。  
  1-n-n*n  
  如果在关系数据库已经可以处理的情况下;再添加中间管理结构,肯定要以牺牲运行效率为代价。  
  Top

53 楼marry2000()回复于 2006-06-17 19:11:07 得分 0

粗略的看了一下你写的东西,跟我所讲的差太多。  
  而且,就像上面有位兄台说的那样  
  1,基类最好是方法的集合,而不是数据的集合;  
  ,相反的最终的业务类是数据的集合,没有太多自己的方法。  
  要提高后代类的编写速度,不然,要基类干嘛  
  Top

54 楼kfarvid(傻小子)回复于 2006-06-17 19:34:22 得分 0

估计批评都基本上说完了,只能说你的想法很好,但是,这样做确实没有什么必要,就仅此而已,我们讲求的是效率,如果你在子模块中只需要很少的代码就可以实现普通模式中的一堆代码,那才是OO的精髓所在。  
   
  还有就是有效域问题,每一个记录为一个对象,没错,但是,有的数据库设计是设计到多表的,很可能是一个记录或者2个记录为一个对象,甚至是一个表的1条记录+另外一些表的1条记录为一个对象。就像单据(票据)一样,一张单据可以看成一个对象,这单据的每一个消费项目看成一个对象,或者是某天的营业额为一个对象,在不同范畴,一个对象的理解是不同的,无论如何,如何看待对象,都要从开发效率以及功能出发,去考虑问题,而不是硬追求这种所谓的OO。OO靠的就是要灵活。Top

55 楼hlp912(孤枕難眠)回复于 2006-06-17 22:11:52 得分 0

路过Top

相关问题

关键词

得分解答快速导航

  • 帖主:cjianwen
  • liangqingzhi
  • lee576
  • whbo
  • wudi_1982
  • 78hgdong
  • cncharles
  • GARNETT2183
  • GARNETT2183
  • zzzl

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo