当前位置:编程学习 > Delphi >>

数据库的一种完全面向对象设计模式(包含实例)Rayphrank原创!

数据库的一种完全面向对象设计模式   

 

1.1 完全面向对象和非完全面向对象

     面向对象(OO)方法这个名字早已深入人心,它的科学性和合理性也已毋庸置疑。人们动辄将自己开发的软件冠以“采用面向对象方法设计”以示其先进性就是一个极好的证明。然而,一个先进的方法学必须有相应的工具支持才能实现,它的概念和方法如不落实程序实现上,就不能真正掌握它的精髓而在实践中运用。诚然,SmallTalk语言已被公认是一个面向对象语言,但是它对于开发者来说是多么的陌生!C++也可以说是一个OO语言,不过从名字就可以看出他是C语言的一个变种。它实现了从过程式编程到面向对象编程的一个较好的过渡。但是许多声称用C++制作的软件其实仍旧是C软件!这是因为没有真正掌握OO方法的缘故。


      即使开发者的开发环境,开发工具是支持OO的(如Delphi,VC),但开发者没有以OO的观点去观察软件的问题域,或者以往的过程式设计思想根深蒂固,那么开发出的软件仍旧是披着OO这件漂亮外衣的过程化软件。没有把OO作为一种确实实用的方法学。造成这种现象的原因是没有认识到OO的精髓,尤其是在一些RAD开发工具下,更容易忽视以OO的观点去观察问题域。


      RAD开发工具开发的软件常能分成两种形式:完全面向对象设计和非完全面向对象设计。一个数据库软件系统的体系结构常能分为三层:用户接口层、中间件层和数据库层。在用户接口层,常是一些具体与用户交互的对象,如:按钮、菜单、和对话框。在数据库层,则是从问题域中找出描述实体的表。完全面向对象和非完全面向对象的最大区别在于中间件层,什么是中间件层,中间件层是问题域中具体对象,商业规则,更高层次上的问题实体。完全面向对象有中间件层,非完全面向对象没有中间件层。RAD工具开发时常会忽视中间件层。


       举个例子:一个简单的记帐系统如果用RAD工具(如:Delphi)开发,用户接口层是一些系统中所用的控件,如按钮,菜单等,这些控件对象由Delphi或其它开发工具中的类库封装;数据库层则是在数据库系统(如SQL SERVER、Oracle等)建立的表,如顾客表、产品表、订单表等。


       完全面向对象设计中的中间件层为问题域的交易,商业规则等对象,以及更高层次上的问题实体,如顾客,产品,订单。非完全面向对象则没有中间件层这些对象。换句话说,非完全面向对象是基于用户接口层直接存取数据库层,即:基于控件。完全面向对象是将中间件层封装数据库层,用户接口层使用中间件层,这样将数据库层完全透明,做到数据与界面的分离,即:面向对象,基于控件。


       在一些小型的系统中,非完全面向对象设计可以加快开发速度,但系统的灵活性,重用性不好,大型系统必须采用完全面向对象的开发方法,否则,由于商业规则没有放在一起,软件后期将不可控制,一个成功的可复用的商业软件应该是由中间件层的众多对象组件灵活搭配而成。


       由此,笔者提出一种数据库完全面向对象的设计模式。

1.2数据库的一种完全面向对象设计模式
    
       用完全面向对象的方法做一般的应用程序比数据库程序容易一些,因为它不涉及到数据库存取。但在做数据库程序时应该考虑类跟跟数据库是怎样联系的。

步骤1:分析问题域,找出所有问题域中相关事物,从中抽象出对象。

步骤2:从抽象出的对象中找出所有的持久对象(Persisitant Object),所谓持久对象就是由数据库管理系统负责管理的,可以永久保留,将来可被提取的对象,将这些持久对象以“一类一表格”的原则映射到数据库中,通过数据库管理系统建立表格。

步骤3:定义持久对象,所有持久对象均采用“双构造函数”的方法在程序中进行构造,其中,一个构造函数参数为所有初始化该持久对象的值,封装数据模块中“存”操作,另一个构造函数的参数为唯一标识该持久对象的值,封装数据模块中“取”操作。其它数据库操作由持久对象相应方法封装。

步骤4:所有与数据库层发生交互的动作,均放在专门的数据模块中,由中间件层持久对象相应方法封装,做到数据与界面的分离。


步骤5:定义其它非持久对象。具体软件功能由相应对象协同实现。


      该设计模式的重点在于持久对象的定义,除了双构造外,持久对象如果一次获取数据数量>1,那么可以定义“持久对象集”对象,“持久对象集”对象由持久对象组成,“持久对象集”对象中的对象集可由数据模块中相应的SQL语言筛选,如果数据集中数据数量非常大,那么在数据模块中相应的SQL语言可以以固定数量进行筛选数据集,分批筛选。对象集中的相应持久对象可用链表的结构进行链接。
以这种方式定义的持久对象,完全封装了数据库存取,用户在使用持久对象的时侯甚至感觉不到数据库的存在,因为相应的数据库操作已被持久对象的相应方法封装,用户只需要建立相应的持久对象即可进行数据库的操作。

 

2.数据库完全面向对象设计模式在银行储蓄管理系统中的实现


2.1问题域对象、持久对象与数据库表


根据上述设计模式的思想,我们首先找出问题域的所有对象
1. 帐户对象
2. 储蓄帐户对象
3. 定期储蓄帐户对象
4. 活期储蓄帐户对象
5. 银行卡帐户对象

       其中储蓄帐户对象、银行卡帐户对象继承自帐户对象,帐户对象为一个虚基类,定期储蓄帐户对象、活期储蓄帐户对象继承自储蓄帐户,储蓄帐户对象为一个虚基类
UML类层次图(图12)

图12:帐户对象UML类层次图

 


6. 储户对象
7. 柜员对象
8. 交易对象
9. 费用对象
10. 利率对象
11. 特殊操作对象
12. 系统信息对象
13. 银行功能对象
14. 银行服务对象
15. 储蓄服务对象
16. 银行卡服务对象


     其中储蓄服务对象,银行卡服务对象继承自银行服务对象,银行服务对象是一个虚基类


UML类层次图(图13)

图13:服务对象类层次图

 

      然后,我们分析问题域,将要持久存储在数据库的数据对象确立为持久对象。
所确立的持久对象为:
1. 储蓄帐户对象
2. 定期储蓄帐户对象
3. 活期储蓄帐户对象
4. 银行卡帐户对象
5. 储户对象
6. 柜员对象
7. 交易对象
8. 费用对象
9. 利率对象
10. 特殊操作对象
     这些持久对象将以“一类一表格”的原则映射到我们选择的数据库SQL SERVER2000中,由此确立数据库中所建立的表格与字段为:


2.2 问题域对象的定义


(1) 双构造函数的使用。


     限于篇幅,本文以持久对象——储户对象为例,说明持久对象的双构造函数方法,其它持久对象的定义思想与之大致相同。

储户对象接口定义
type
  TCustomer = class(TObject)
  private
    { Private declarations }
  protected
    { Protected declarations }
    Cus_id:string;
    Cus_name:string;
    Cus_shenfenid:string;
    Cus_addr:string;
    Cus_phone:string;
     procedure New_Cus_Info(c_name,c_sfid,c_addr,c_phone:string);
     procedure Load_Cus_info(cusid:string);
  public
    { Public declarations }
    constructor create(c_name,c_sfid,c_addr,c_phone:string);overload;   //(1)
constructor Create(cusid:string);overload;                        //(2)

    function update_cus():boolean;
    procedure Set_Cus_Id(C_Id:string);
    procedure Set_Cus_name(C_name:string);
    procedure Set_Cus_shenfenid(sfid:string);
    procedure Set_Cus_addr(addr:string);
    procedure Set_Cus_phone(phone:string);
    function Get_Cus_Id:string;
    function Get_Cus_name:string;
    function Get_Cus_shenfenid:string;
    function Get_Cus_addr:string;
    function Get_Cus_phone:string;
  published
    { Published declarations }
  end;


     根据数据库完全面向对象设计模式,持久对象将由两个构造函数(见(1)、(2)),其中第一个

补充:软件开发 , Delphi ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,