第3章 数据和对象

转载 2006年06月06日 10:18:00

第二部分 应用服务层的设计

第3章   数据和对象

31数据的形态

在应用软件系统中,首先要处理的对一个对象就是数据。应用软件系统,主要目标就是采集数据、处理数据、分析数据、察看数据。对于软件,诚如有一句名言所说:“软件,就是数据结构加算法”。

在软件中,数据有多种表现形态。

首先,在程序中,数据总是以某种数据结构的方式被表示出来,这种表示,通常被编译成二进制文件存在于硬盘上,并且在运行时刻在内存中被实例化。

这种数据结构有多种表达的方式,简单的情况下,他可能只是一个数字,或者一个字符串,用某个变量来描述。例如,为了表述某种商品的价格,可能使用如下的申明来表述这个数据:

 

double price = 100 ;

 

现实中要处理的数据总是比较复杂的,为了描述一个完整的信息,通常要组合多项简单的数据,例如,为了描述某种商品的信息,通常需要描述他的名称、价格、重量等。在传统的C语言中,可以使用结构来描述:

 

struct product

{

    char* name;

    double price;

    double weight;

}

 

在面向对象的语言里,类似的数据结构,可以使用类来表述。上面的代码可以用Java语言表述如下:

 

public class Product

{

    public String name;

    public double price;

    public double weight;

}

 

可以看出来,实际上两者的差别是非常小的。

对于更加复杂的数据结构,一个类可能引用到其它的类,例如,上面的Product,可能有一个Size属性,而这个Size属性,也有heightwidth构成,那么,整体的数据结构就可以描述如下:

 

public class Product

{

    public String name;

    public double price;

    public double weight;

    public Size size;

}

public class Size

{

    public int height;

    public int width;

}

 

数据的另外一种表现形态,就是永久化保存的形态。上面描述的数据的形态,是一种“瞬时”的数据,只有在程序运行的时候才存在于内存中,一旦程序结束,或者数据处理结束,数据就从内存中清楚。在很多情况下,需要把处理的数据保存到磁盘上,这时候,数据就进入永久化保存状态。

可以有多种保存数据的格式。可以把数据保存为普通文本文件存放在磁盘上,或者,也可把数据保存在XML文件中。在JavaC#中,也都提供了这样一种能力,就是可以把对象序列化后保存到磁盘上,然后,在需要的时候,可以反序列化成对象。

虽然有多种持久化保存数据的方案,然而其中使用关系型数据库来保存数据,无疑是最常用的办法和最可靠的办法。这就引伸出一个在面向对象的系统设计中的常见问题:对象/关系型映射(O/R Mapping)

在考虑O/R Mapping的时候,有两个概念是经常会接触的,那就是VOPO

所谓的VO,就是Value Object,这种对象,只包含了对象的数据,而没有状态,或者说,处于瞬时状态。VO可以用来在层之间传递数据

所谓PO,就是Persistent Object,就是持久化保存的对象,这种对象,一般是有状态的。O/R Mapping框架需要根据PO的状态,来执行相应的同数据库的交互。关于PO的状态,我们在后面再讨论

 

32对象/关系型映射

对象关系型映射,最核心的要完成两个功能:对象和关系型之间的映射规则,以及两者之间的相互转换。

除了这两个基本的功能,一般的O/R Mapping产品还会加上一些额外的特性和功能,以加强产品的功能,为软件开发提供更多的方便和提高性能。一些常见的功能,例如缓存。

现在有一些典型的O/R Mapping框架可以参考和使用,比较著名的有EJB中的Entity BeanJDOHibernate等,这些方案都是基于Java的。在Microsoft.Net平台下,相对来说可供选择的方案比较少,其中有一个开放源代码的方案Websharp,可以从 www.websharp.org 下载。

我们在实际开发中,可以选择使用已有的解决方案和产品,也可以自己设计自己的O/R Mapping框架。当然,无论采用何种方式,都需要我们对O/R Mapping的基本原理和方法有一个基本的了解。

在支持OO的语言中,继承是语言的基本特征。O/R Mapping的框架,也需要对继承做出相应的支持。一般说来,有三种继承模式:ONE_INHERITANCE_TREE_ONE_TABLEONE_INHERITANCE_PATH_ONE_TABLEONE_CLASS_ONE_TABLE

Ø   ONE_INHERITANCE_TREE_ONE_TABLE

一个继承树映射到一个表,即将具有相同父类的所有类都映射到一个数据库表中,这些类属性映射的集合组成这个表的列,在这种模式下,只需要对最底层的类进行映射。

如下面一个类结构:

 

 

 

在这个类结构中,父类Parent有两个子类Child1Child2,父类有属性Property1Property2Child1新增了一个属性Property3,而Child2新增了另外一个属性Property4,当采用ONE_INHERITANCE_TREE_ONE_TABLE映射模式的时候,数据库中只有一张表,结构如下:

 

 

 

其中,Column1Column2字段分别对应Parent类的Property1Property2属性,Column3字段对应Child1Property3属性,而Column4字段对应Child2Property4属性。Column3对于Child2Column4对于Child1是没有意义的。

采用这种映射模式,优点是比较简单,缺点是数据的冗余比较大。这个表要容纳所有的子类的字段,很多字段只是对某个类有意义,而对于其他类则没有意义,是纯粹多余的,并且,在继承树中新增一个继承节点的时候,往往导致表的字段的重新设计,这是一件非常麻烦的事情。

 

Ø   ONE_INHERITANCE_PATH_ONE_TABLE

一个继承路径映射到一个表,即将一个类映射到一个数据库表中,这个类的所有属性(包括从父类继承来的)映射的集合组成这个表的列。

在这种模式下,对于上面的类结构,数据库的结构就是:

 

 

 

其中,表Child1Child2分别对应于类Child1Child2

这种模式是非常常用的,也没有数据冗余,缺点是在搜索的时候比较麻烦。例如,当我要搜索符合某个条件的Parent对象的时候,需要同时搜索Child1Child2表,并且,当在继承树中新增一个继承节点的时候,需要新增一个表,搜索的范围也必须扩大,原来的程序可能不得不重新设计。

 

Ø   ONE_CLASS_ONE_TABLE

一个类映射到一个表,即将每个类映射到对应的一个表,这个类的属性(不包括从父类继承来的非主键属性)映射组成这个表的列,在这种模式下,具有继承关系的类被映射到不同的表中,表之间通过主键关联。

在这种模式下,对于上面的类结构,数据库的结构就是:

 

 

 

Parent作为Child1Child2的父表,父子表之间通过主键Colimn1关联。

这种模式是非常容易理解的,因为和类图非常相像,缺点是在查询的时候,由于设计到表的关联,SQL语句会比较复杂,效率也会比较低。这个情况当继承数的深度增加的时候,会体现的比较明显。

如果一个类没有子类和父类,那么采用三种模式中的哪一种都是一样的效果。

 

 

33对象的状态

为了很好的控制对象,以及在同后台存储交互时的行为,通常O/R Mapping框架需要维护PO对象的状态。在不同的框架中,对对象状态的定义不尽相同,不过,也都有一些共同点,某些方面可能只是名称的不同。通常的O/R Mapping框架都需要以各种方式来直接或间接的处理PO的这些状态。下面列出的一些状态是一些基本的,比较共通的一些状态

Ø   Transient

Ø   Persistent-new

Ø   Persistent-dirty

Ø   Persistent-clean

Ø   Persistent-deleted

Transient

在这种状态下,对象处于一种“瞬时”的状态,还没有同任何数据库的数据相关联,对象也不受O/R Mapping框架的运行时控制,对象的表现就是一个普通的类的实例。

比较典型的,在JDO里面,对于Transient的状态的说明如下:

JDO instances created by using a developer-written or compiler-generated constructor that do not involve the persistence environment behave exactly like instances of the unenhanced class.

There is no JDO identity associated with a transient instance.

There is no intermediation to support fetching or storing values for fields. There is no support for demarcation of transaction boundaries. Indeed, there is no transactional behavior of these instances, unless they are referenced by transactional instances at commit time.

When a persistent instance is committed to the datastore, instances referenced by persistent fields of the flushed instance become persistent. This behavior propagates to all instances in the closure of instances through persistent fields. This behavior is called persistence by reachability.

No methods of transient instances throw exceptions except those defined by the class developer.

A transient instance transitions to persistent-new if it is the parameter of makePersistent, or if it is referenced by a persistent field of a persistent instance when that instance is committed or made persistent.

意思是说,

 Persistent-new

这种状态,表示一个新的可持久化对象,该对象还没有被保存到存储介质中。在这种状态下,当事务结束被提交的时候,框架会执行一个插入的操作,将对象保存到存储设备中。

 

Persistent-dirty

这种状态,表示一个对象是可持久化的对象,已经对应于数据库中的某表记录,但是,在程序中,该对象已经被编辑过,与数据库中的数据并不同步。在这种情况下,当事务被被提交的时候,框架会执行一个更新的操作,将对象和数据库同步。

 

Persistent-clean

这种状态,表示一个对象是可持久化的对象,并且与数据库中的数据是同步的。

 

Persistent-deleted

这种状态,表示一个对象是可持久化的对象,并且该对象已经被删除。在这种情况下,当事务被被提交的时候,框架会执行一个删除的操作,将数据从数据库中删除。

lua程序设计第二版 读书笔记(5-8章)

书本下载地址                       http://download.csdn.net/detail/myy2012/5349646 本部分下载地址               ...
  • myy2012
  • myy2012
  • 2013年05月09日 17:04
  • 1207

第3章 数据和对象

第二部分 应用服务层的设计第3章   数据和对象 3.1数据的形态在应用软件系统中,首先要处理的对一个对象就是数据。应用软件系统,主要目标就是采集数据、处理数据、分析数据、察看数据。对于软件,诚如有一...
  • jane082
  • jane082
  • 2006年06月04日 19:21
  • 560

《Drools7.0.0.Final规则引擎教程》第4章 4.1 规则文件

一个标准的规则文件的格式为已“.drl”结尾的文本文件,因此可以通过记事本工具进行编辑。规则放置于规则文件当中,一个规则文件可以放置多条规则。在规则文件当中也可以存放用户自定义的函数、数据对象及自定义...
  • wo541075754
  • wo541075754
  • 2017年07月15日 11:30
  • 1684

Java - Thinking in Java 第2章 练习

Thinking in Java1//: object/HelloDate.java /** * Default initialize class. * @author C.L.Wang * @...
  • u012515223
  • u012515223
  • 2015年07月06日 23:14
  • 1393

《 Thinking in Java 》_第3章_操作符_练习题

如果熟悉C或C++的语法,那么只需快速浏览本章和下一章,看看Java与这些语法直接的差异。如果觉得很难理解这两章内容,可以去网站免费下载多媒体课程《Thinking in C》,可快速掌握学习Java...
  • waterydd
  • waterydd
  • 2017年04月19日 10:32
  • 418

JavaScript+DOM编程艺术 第三章 DOM

DOM简介1.HTML DOM:网页被加载时,浏览器会创建文档对象模型 2.DOM操作HTML:改变HTML的元素、属性、CSS样式、对所有事件作出反应DOM操作HTML不要在文档加载完成后使用do...
  • qq_34664510
  • qq_34664510
  • 2017年07月10日 21:34
  • 211

Netty In Action中文版 - 第三章:Netty核心概念

注:本篇内容出自《Netty In Action》一书;         注:本人原创译文,转载请注明出处!...
  • abc_key
  • abc_key
  • 2014年07月12日 11:34
  • 11694

《深入剖析Tomcat 》第3章 连接器(Connector)

第3章  连接器(Connector) 3.1  概述 在简介一章里说明了,tomcat由两大模块组成:连接器(connector)和容器(container)。本章将使用连接器来增强ap...
  • u011345136
  • u011345136
  • 2015年04月27日 14:58
  • 393

第三章 Dom操作

浏览器中的Dom文档对象模型Dom是独立于语言的,用以操作XML和HTML文档的程序接口(API)。在浏览器中的接口通常是以javascript操作的,因此大多数的脚本都在与DOM打交道。Dom和ja...
  • yangyiboshigou
  • yangyiboshigou
  • 2017年05月18日 18:59
  • 202

统计学习方法 第3章 k近邻法

统计学习方法 第3章 k近邻法算法k近邻法:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最临近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。训练数据集: 其...
  • super_chicken
  • super_chicken
  • 2017年11月16日 13:03
  • 86
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第3章 数据和对象
举报原因:
原因补充:

(最多只允许输入30个字)