实体定义:每一层都不相同,对于层间实体之间映射的一点思考

实体关系图是我们在做设计的时候必定要做的一件事情,现在很多人都在用UML做,不过实体关系图依然是不可缺少的一个有效的数据分析方法。

一提到实体关系图,很多人就立刻联想到数据库,我自己也是这样。在实际工作中,我们经常会需要去考虑把数据库中的表结构映射到数据结构中来,然后用类似如下的代码来完成我们的工作:

// 上个世纪的代码,伪代码
DBCommand command = GetSQL("select * from xxx where ");
string name = command.GetString("Name");
int age = command.GetString("Age");


// 这个世纪的代码,伪代码
class HumanInfo
{
  
string Name;
  
int Age;
}


HumanInfo info 
= (HumanInfo)NHibernate.Load();

但是大家是否发现了,因为使用的数据结构和表结构基本一一对应,所以我们有时候使用起来会变得非常繁琐,比如要获取一个好友的名字,我们也许要用这样的代码: FindPeople(man.FriendID).Name。其实如果不考虑数据库的话,最佳方法也许应该是这样: man.BestFriend.Name。我们为什么不能让自己用最有效率的方法来定义数据结构呢?

这就是我们本文所需要讲述的问题,不过我思考的还不是很深入,所以期盼大家一起跟我来交流。

一般一个应用程序都至少可以划分为三个层次:界面层,业务层,数据层。我们目前的实体定义基本都只考虑在数据层,也就是实体定义等同于数据库表结构定义。但是实际上,这三个层次都有着不同的实体定义需求。我们拿一个简单的“个人人际关系”例子来做示例,看看每一个层次对于实体的需求差别在哪里。

1。界面层

界面层的主要对象是用户,对于用户感觉有意义的界面内容包括如下:
姓名,年龄,生日,所在地区(省、市),电子邮件1、电子邮件2、电子邮件n,电话1、电话2、电话n,最后联系时间,关系网(认识人1、认识人2、认识人n)

加入我们的这个程序是给大众用户使用的,所以我们就不能在界面上出现什么代号0016之类的东西,能用汉字的都需要尽量用汉字表示,比如所在地区就不能简单用电话区号或邮政编码来代替,必须要显示“湖南长沙”之类的文字。

而且更加重要的是,这些用户和程序员不一样,他们没有“集合”、“关联”的概念,任何试图暴露概念给最终用户都是不应当的。界面层最主要考虑的问题是表达性,“没有歧义”和“一目了然”是它追求的目标。

2。业务层

接触业务层的主要是程序员,对于程序员需要有意义的内容及其组织方式,如下的定义应该是比较合理的:

public class People
{
 public string Name;
 public int Age;
 public DateTime Birthday;
 public AreaType Area;
 public MailBoxCollection MailBoxs;
 public DateTime LastComm;
 public PeopleCollection Relations;
}

public class AreaType
{
 public int ID;
 public string Name;
}

业务层需要考虑的问题明显就比界面层要多了,这里不仅需要考虑易用性的问题,也需要考虑性能问题。比如PeopleCollection的定义中,就需要考虑其中是包含一个People呢还是仅仅是一个PeopleID,这些问题如果考虑不清楚,会给接下来的和数据层之间的交互带来大问题。

3。数据层

数据层当然就是要描述数据库表结构了,但是也不是严格地要完全一致,但是抽象不宜太大,以免影响效率。不过国内的系统一般都是定制的,所以很多项目都直接采用表结构定义作为数据层的实体定义。以上一个简单的定义,到数据层就变得非常庞大,我用图表示如下:
绘图1.gif
从上我们可以看到,因为每一层面对的使用者不一样,导致了各层对于实体数据的定义要求也不一样。实际使用中因为各种因素的制约(项目进度、预算、人员能力、设计强度等),导致我们经常有意无意地忽略了这样的差异。而忽略各层之间实体要求差异性的后果,则是我们经常有意无意地把我们最底层的概念带到用户面前,看看我们系统中不断弹出的输入框吧(比较一下M$的office和exchange等软件);也经常因为底层数据的限制,导致某些功能无法持续改进;最可怕的是一旦客户需求有所改变,从头改到底的工作量和难度经常让我们十分畏惧。

有没有工具让我们很轻易地完成这些工作呢?也许将来会有的,但是前提是我们要找出这个数据变换的规律来。毛主席说,自己动手,丰衣足食。我们就自己动手先来找一下看看。

首先是界面层到业务层的数据变换规律。在这个变换过程中,“字典映射”的方法占了很大的比重,比如我们要把“所在地区”的内容从汉字变到一个AreaType对象,把“认识人”从名字变成一个PeopleId等,目的是减少数据的重复性和冗余度,把无序变成有序。

其次是业务层到数据层的数据变化。在这个变化中,“关联”方法占了较大的比重,为了方便编程,我们把很多数据都冗余了起来,要把业务层数据放到数据层,就需要继续瘦身。

刚写到这里,忽然想到,其实三层之间的数据转换,其实就是数据库第一第二第三范式的转化过程阿。看来又要补课了。


posted on 2005-03-23 13:32  老翅寒暑  阅读(2872)  评论(5编辑  收藏  举报

导航