比如我的软件要实现如下功能:可以打开多种格式的文件并显示、处理。我现在的做法是:针对每一种格式的文件,写一个打开函数,写一个显示处理函数。由于不同格式的文件都是由文件头+数据段组成,而且某些处理显示方法差不多。确实在这些函数中存在重复的代码,但由于参数不同等因素,很难合并这些函数。
最近看了一些关于oop方面的书,按oop的思路,我是不是应该先定义一个对象(文件对象),然后定义多个类(每种格式的文件一个)和它们的属性等。然后呢?
我怎么看不出oop思想的先进性呢?比如:当需要多显示处理一种格式的文件时,我只需写2个处理函数就行了,这样很麻烦吗?
现在的参考书都以概念为主,不结合具体的例子,很难理解和体会,谁能针对我举的例子说说oop的好处和使用的具体办法?
  

解决方案 »

  1.   

    针对你的问题,你可以这样设计:
    建立一个文件基类,里边包括文件打开函数,在打开函数中调用另一个处理不同文件内容的函数,后者作为虚函数存在,然后为每个不同的文件格式派生新的类,在所派生的类中重写基类中定义的虚函数。
    TMyFile = class
    public
      procedure Open(...);
      procedure View(...);
    protected
      procedure OpenHelper(...); virtual;
      procedure ViewHelper(...); virtual;
    end;TMyDocFile = class(TMyFile)
    protected
      procedure OpenHelper(...); override;
      procedure ViewHelper(...); override;
    end;implementationprocedure TMyFile.Open(...);
    begin
      //进行所有文件格式相同的操作
      //.......
      OpenHelper(...);//OpenHelper函数进行不同文件格式的差异处理
      //......
    end;..........
      

  2.   

    可以看出yrb兄很了解类了--你的名字像rmb :)其实class的好处不仅在于代码重用,更在于他的封装,继承等特性。比如在一个很大的工程中用到经常用的几个方法,你就可以写成dll,class等
    封装起来,用到了就直接调用,如果这种方法的函数需要修改,就直接修改dll,class
    大大提高了效率,这是代码封装重用的好处。更有用的是他的继承性,就如所示:这是一个父类,TMyFile = class
    public
      procedure Open(...);
      procedure View(...);
    protected
      procedure OpenHelper(...); virtual;
      procedure ViewHelper(...); virtual;
    end;
    这是一个继承基类方法函数的子类
    TMyDocFile = class(TMyFile)
    protected
      procedure OpenHelper(...); override;
      procedure ViewHelper(...); override;
    end;
    这个子类不仅有自己的方法,而且能用父类的方法。
    不仅代码重用,而且实现了模块化编写。
    在编码维护方面更有所长。
     oo的体现了对特定事物模型化处理的思想。
    是通过对一类物体的行为属性的集合处理在
    计算机上实现的。
     。
     还有很多。。
     等你有机会参与大型项目的开发,你就知道了
     特别是用vc的体会更深,
     如果你想成为一个真正的pm,那么用vc吧。
     delphi 是开头容易后来难。
     vc相反---我的体会
      

  3.   

    考虑这种情况:你要支持100种文件格式(而且有可能不断增加)
    1、使用函数,你要写100个打开函数,100个显示函数,然后调用:   case filetype(sType) of
         ftType1 : opentype1(filename);
         ftType2 : opentype2(filename);
         ...(省略98个)   
       end;   调用显示函数也是如此,考虑一下,如果你要实现更多的功能,比如搜索等等,每种功能调用的时候你都要有一个长达100多行的case调用。2、使用类:  参考 yrb() 的代码创建基类,  功能调用
      case filetype(sType) of
        ftType1: FileObj := TFileType1.Create;
        ftType2: FileObj := TFileType2.Create;
        ...
      end;
      
      FileObj.Open(filename);
      FileObj.View;
      // 如果增加了新的功能,只要在此增加
      FileObj.OtherFun;不说其他的,由此就可以看出oop的优势。
      

  4.   

    TDealFile = class
    public
      //这里可以进行一些通用的设置
      procedure Write; virtual;
      procedure View; virtual;
    end;TDealFileChild1 = class(TDealFile)
    public
      procedure Write; override;
      procedure View; override;
    end;
    TDealFileChild1.Write;
    begin
      inherited;
      //这里进行此类型文件的设置
    end;TDealFileChild1.View;
    begin
      inherited;
      //这里进行此类型文件的设置
    end;先说2个好处:
    1.每增加一个文件类型,通用的设置部分代码就不用Copy过来了,修改了就所有的子类全部都改好了.然后每个子类又可以进行自己的设置.
    2.所有的类都用同样的函数名来调用.不用记忆繁多的函数名.结合设计模式,可以再设计一个通用的类来管理这些类.
    比如(简单点,用一个函数表示,实际情况当然会复杂得多):procedure CommonWrite(filetype:Integer);
    begin
      case filetype of
        0:DealFileChild1.write;
        1:DealFileChild2.write;
        2:DealFileChild3.write;
        .....
      end;
    end;这样管理起你的文件类型,是不是方便很多,只需要知道2个函数和文件的类型,就可以自动处理了.
      

  5.   

    我个人认为在oop里主要是在于他的封装,继承等而实现代码重用。
      

  6.   

    按刘艺《模式编程》里面的建议用Bridge模式是比较合适的。
      

  7.   

    我也刚学面向对象,与楼主有一样的同感啊.
    回复人: mastersky(浪) ( ) 信誉:97 
    的解释比较清楚.
    但我要用结构化模块化的设计的话:那我可以,1、将公用操作提炼为一函数(如同提炼出来的基本类中的公用方法)。2、将打开文件操作做一个功用打开函数使用case fileType of .... end;这样我打开的时候用这个函数传入文件名和类型即可。3、显示也如同打开一个再加个公用显示函数。
    但是比较一下还是用面向对象技术好啊,最少我看到只要在创建的时候判断类型即可,打开,显示都不用判断了。
      

  8.   

    不用面向对象,你的代码里面会有一堆的if...else...或者case语句,很难阅读。处理的地方多了之后,也很难修改。用面向对象可以避免这些问题
      

  9.   

    你可以通过阅读Delphi的代码看出来。其次, 你可以多读读面相对象的书, 我在大学看了很多本,一直未曾体会到,直到实习的时候用Java开发的时候才体会到。<<面相对象编程导论>>这本书也许可以给你一些帮助。其实相关方面的书很多,书读多了,自然就能体会到的。
      

  10.   

    OO的精髓现在更趋于inherited而不是重用。看看Eclipse,写出一个小巧稳定的内核类,在扩冲吧
      

  11.   

    如果文件格式很多的话可以通过ini文件或者桌面数据库如Access建立模版
    先定义一个类或者纪录TFileStruct用来表示文件的格式在TMyFile里里声明一个TFileStruct类型的变量CurrentFileStruct:TFileStruct;
    每次改变文件格式时在TMyFile里调用他的initialFile初始化函数初始化CurrentFileStruct