OOP的一项原则是业务处理层和用户界面分开,在三层结构或“瘦客户”的两层结构中业务处理多放在中间层或由服务器的存储过程或触发器完成,客户端只负责与用户交互。但有时为了减轻服务器的负荷在两层结构的C/S系统中客户端程序有时也需要运行一些业务处理。我的设想是把这些业务处理以类来封装,结果叫由form显示。
   这些业务处理类必然要封装数据访问成员,delphi的数据访问控件为TDatabase,TTable,TQuery等控件,这些控件有自己的消息处理函数,因此要放在一个Form或DataModule中才能响应消息,如果作为一个直接继承自TObject的类的成员 这些数据访问控件怎样接收和处理消息呢?(没有窗口句柄怎样接收和处理消息?)
    所以这些业务处理类是不是要以一个Form存在,只是它不在屏幕上显示?那么建立一个对象就要用CreateForm而不应该用new了。同理,在中间层应用程序服务器封装不同的业务逻辑是不是也要用这种方法?

解决方案 »

  1.   


    所以这些业务处理类是不是要以一个Form存在,只是它不在屏幕上显示?新建一个unit,或直接创建一个dll工程,把业务处理类放在里面不是更好吗?
      

  2.   

    to zsjzwj(北极熊)
        单个业务处理类当然是放在单个unit中,form在project中也是一个unit,我的问题是业务类是从TObject还是从TForm继承,因为delphi的数据访问控件可以响应消息,在delphi中TObject没有消息处理能力,TForm可以,所以要完全发挥数据控件的功能要把数据访问控件放在一个form中。我粗略地研究了一下delphi的数据模块TDataModule类,其实数据模块也是一个form,只不过被隐藏罢了。但delphi对数据模块类的数量有限制,好象每个project只能有一个TDataModule,我试过加了两个TDataModule但编译时出错。
        如果不把数据访问控件放在form中也可以,我曾经写过一个业务处理类,从TObject继承,数据成员包括一些数据访问控件如:Dataset:TQuery; 数据控件放在DataModule或其他窗体中,在业务处理类初始化时把数据控件的指针赋给类的Dataset成员,这样也可以。但这样做业务处理类就依赖其他类,内聚性低。不符合“低耦合高内聚”的原则。
       另外,我还没写过dll,要是要做成dll又应该怎样设计?
      

  3.   

    >>>>>>但delphi对数据模块类的数量有限制,好象每个project只能有一个TDataModule,我试过加了两个TDataModule但编译时出错。
    我的项目就是用两个DataModule,跑的好好的。用类来封装当然是好事,但一味的强调类封装会把自己逼进死胡同的。对于一个好的设计,我个人认为关键是接口设计,一个好的接口设计会让每个部分自由的发挥,还不受制于其他模块,做到真正的独立性。
      

  4.   

    1.不要把消息和Windows消息混为一谈,从TObject派生的一样可以处理消息,在这里已经实现了处理消息的流程2.你指的消息处理应该是事件驱动吧?其实这个了解事件驱动的本质就很明白了,这里是在一个成员变量中保存一个对应某事件的成员函数地址,然后可以在消息函数中调用.这一步在任何时候都能完成,XXX.OnDoSomething := MyClick;.C++中没有事件的概念,不一样可以OOP吗?3.如果是控件就必然要和UI打交道,你用的那些叫组件:)
      

  5.   

    我觉的你这个论论仅仅限于MVC上的讨论;
    UI分离,不就是体提在MVC上吗?视图的多元化;_____________________________________________________________________暮春三月,羊欢草长,天寒地冻,问谁饲狼?人心怜羊,狼心独怆,天心难测,世情如
    霜……{言有尽而意无穷,余意尽在不言中……}
      

  6.   

    sundayboysII(空)
    在多层系统中,你所说的这种情况根本不存在;
    为了处理大量DataSet给DataModule代来的压力,我们不得不建立多个RDM是常有的事;_____________________________________________________________________暮春三月,羊欢草长,天寒地冻,问谁饲狼?人心怜羊,狼心独怆,天心难测,世情如
    霜……{言有尽而意无穷,余意尽在不言中……}
      

  7.   

    faint,我复制的是楼主的话,不是我说的阿,我说的是可以阿,因为我现在经常用多个DataModule的。
      

  8.   

    to  sundayboysII
       早上事太多,现在才看大家的讨论。可能是我操作错了,我在一个project中用两个datamodule在编译时的确会报错,下午我再试试。我认为我的问题关键就是我要生成一个类,这个类可以中封装了delphi的数据访问控件如TQuery等,类要可以响应和处理数据访问控件的消息,关键是这些类从哪里继承?TObject?TDataModule?TForm?
        看了楼上各位大哥的回贴我发现我还有很多东西还要学习。
      

  9.   

    >>>类要可以响应和处理数据访问控件的消息??是指自定义消息还是指其他什么?以及你这个类要具有什么样的属性,这个才是决定你从哪儿继承的关键。
      

  10.   

    我所指的“响应和处理数据访问控件的消息”是OnPost,BefroPost之类消息,当然自己也可以自己加。
      

  11.   

    OnPost、BefroePost这些都是事件不是消息!!!也就是说你创建了AODQuery,这些事件就已经有了,只是在你创建的时候和自己写的事件绑定一下就可以了。
      

  12.   

    昨天成功测试了一个多DataModule的项目,发现是我以前操作错了。这几天发现我虽然用delphi有一段时间了但对他的了解还是很肤浅,delphi的OOP方面的书又很少,希望大家继续关注这方面的问题。
    李维的《Inside VCL(深入核心——VCL架构剖析)》出了,大家认为有没有购买的必要?
      

  13.   

    这贴也叫讨论DELPHI和OOP的关系?PS:所有控件都可以在任何UNIT文件里面创建,消除,不需要FORM
      

  14.   

    to  anggogo(angGoGo) 
        问题源于小弟几天前思考关于OOP中关于数据处理层与用户界面层分离的问题,我以前用delphi开发的应用多是把数据访问控件直接拖到form上,如果数据访问控件要与界面分离的话数据访问控件必须放在另一个类(unit)中,但这个类必须可以响应数据控件的事件,我的问题是这个类从哪个类继承,TObject,TForm还是TDataModule?
        我的问题现在基本解决了,但我希望在这里大家继续讨论delphi中OOP的话题。
      

  15.   


    " 我所指的“响应和处理数据访问控件的消息”是OnPost,BefroPost之类消息,当然自己也可以自己加。"
    --->>
      数据集的祖先类是Tdataset,而Tdataset是从Tcomponent继承下来的。因此它没有消息处理.
      这里没有消息处理是说它不能响应window的一些消息。 但可以响应我们自已定义的消息。Tdataset的一些事件如post,beforepost,afterpost等事件,这些事件不是通过消息来驱动的。
     它是通过过程驱动的, 如我现在要保存 我这样写 query1.post 这个时候它会自动先执行beforepost事件。 保存完后再执行afterpost事件。 这两个事件是由post这个事件来驱动的。当然我们也可以手工调用其事件如query1.beforepost 它也会执行。
    以上是我个人的一些看法, 请各位多多指教。