随笔 - 181  文章 - 15  trackbacks - 0
<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(1)

随笔分类

随笔档案

My Tech blog

搜索

  •  

最新评论

阅读排行榜

评论排行榜

5、重构数据库访问代码

我们原来在开发过程当中,常常要求对有关数据库的操作进行一些封装,并把它们独立为一个DAL层。DAL层其实就是一种和持久层的交互媒介。通过这种分层方式,开发者往往只需要修改DAL层的代码就可以满足变更,而不用重写整个应用系统。

伴随着敏捷方法和大型重构的出现,DAL的优势又一次得到了有力的证明:对于那些有关数据库架构的修改所带来的影响只会被限制在DAL层。也只有这样,我们才能够让我们后续的工作足够的少。下图给出了这样一种分层结构:

refactoring9

5.1同步修改数据库模式和数据库访问代码

总体来说,应用系统之所以要保存数据,是为了在之后在读出它们。

refactoring10

当和关系数据库整合的时候,你就不得不创建一些冗余的数据类。业务对象作为数据类需要和数据库中的数据进行对应。所以一旦重构这些业务对象,就不得不同时修改数据库和应用系统。

这就意味着,在重构过程中,有四个潜在的地方可能需要修改:

1、有关这些业务对象的数据库模式。

2、应用程序中定义这些业务对象的类。

3、从数据库读入数据,并将数据装入业务对象的代码。

4、把业务对象的数据持久化到数据库中的代码。

大体上,读和写数据作为直接和业务对象有关的操作,可以任意的放置在系统的任意地方。而一个设计精良的系统至少会保证有关某一个业务对象的持久化操作只会出现在特定的地方。然而不幸的是,在从数据库读取业务对象的数据的时候,你就往往不能够保证这一点了,因为处于一些数据展示方面的要求,有可能会通过连接操作一次性的载入多个对象。

最为常见的重构业务对象的流程为:

1、以增量形式修改数据表:

总是添加新的字段;

要删除的字段在代码中仍然保留,但是被标记为“ 过时”;

通过复制来修改字段,老的字段被标记为“过时”。

2、为新的字段指派合适的默认值。

3、在修改业务对象的时候,要确保新添加字段的数据能够被保存到业务对象中来,同时那些被声明为“过时”的字段仍然能够被提交而不会在运行过程中出现错误;如果必要的话,把那些确实要丢弃的字段声明为“过时”。

4、所有数据的持久化操作必须接受新字段;

5、所有数据的装载操作都必须确保这些新添字段的数据能够读入;所有对那些过时字段进行访问的读操作都应当被淘汰掉。

6、所有的数据持久化操作除去那些对过时字段的写操作。

7、过时的字段从数据库中删除;

8、过时的字段从业务对象中删除。

当然上面这些操作并不是一个通用的操作,他不一定适用于所有的情形。对于特定的重构,这些操作往往需要作出修改。

现在假设我们希望为我们的客户对象添加一个“国家”的字段(也许在以前,我们只接待德国的客户,而现在我们的业务扩展到了全世界)。为了达到这个目的,我们将会首先引入新的字段到类Customer中。这里我们把G(Germany)作为默认值来保存。到现在为止,这个字段既不会被写,也不会被读。

现在继续下一步,我们把新的字段添加到数据库的模式中来,然后我们让每一个新的Customer都会默认得把G当作自己的国家。然后读取Customer数据的操作就可以被修改了,接着是保存。最后新的字段的输入框会被放到GUI上。

简而言之,过程如下:

1、向类中添加新的字段;

2、向数据库模式中添加新的字段;

3、让字段可读;

4、让字段可以保存;

5、在GUI上可视。

每一步之后,我们的软件系统都处在一种一致性的状态中。直到最后一步完成,达到了我们想要的效果。而在这一步之前,系统只能够处理德国的客户。

当然,事情并不是总象我们所想象的那般简单:现在我们假设这样一个例子,我们希望把国家代码以一个数字来代替,而不是这个国家的首字母。为了达到这一点,“国家”字段的类型必须从String型转换为Integer型,这个变化既要应用于程序代码中,也要应用于数据库中。

下面一系列的操作将要完成这个需求:

1、向类中添加新字段,然后指定默认值。

2、修改数据库模式,指定默认值。添加对这个字段进行保存的有关代码;

3、添加用来进行业务对象数据载入的代码;

4、把所有GUI上面有关对于旧字段的访问转换为对于新字段的访问。

5、去除旧字段的载入代码;

6、去除旧字段的保存代码;

7、从类中删除旧字段;

8、从数据库模式中删除旧字段。

注意第一点和第二点:在这里不要使用静态默认值,因为默认值是依赖于已经存在的国家编码的。需要一个额外的算法来计算已经存在的那些国家的数字表现形式。基于这个目的,这个额外的算法有可能去访问数据库中的有关国家、编号对应的表。

进一步看这个过程,你会发现,载入数据和保存数据总是无法在一步完成。事实是,系统中和这两个操作有关的过程往往需要经过多次变动才能满足要求。

当然,让重构的最后一步去处理这些事情是相当诱人的。一旦第三步中有关数据载入的操作被去掉,系统可能开始的时候看上去还不错,但不可避免的就是你可能在一段时间之内得不到存放在数据库中的真正的数值,取而代之的是你的那个默认值。这样的潜在问题会四处爆发,你的相关的代码都不能幸免于难。

posted on 2007-08-23 21:00 littlegai 阅读(201) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理