前言
我希望我的设计和经验的积累可以给你的设计或是开发工作带来一些帮助,我们先看看文章标题的含义:
H代表:HASH(哈希表),是本文会用到的基础概念;
DTO代表:数据传输对象,在绝大部分应用中都需要这样的对象,用以数据的传递,载放和操作,可能有些DTO是比较隐蔽的,但是控制流和数据流分开实现的应用其设计思路更明确,也更受欢迎。
模式(Patterns):模式是一种概念和经验的结合并构成思想,每次说道模式,我们都会想到的《设计模式:可复用面向对象软件的基础》(Design Patterns:Elements of Reusable Object-Oriented Software)一书中描述的23种设计模式, 追其根源却发现它更早的来源始于克里斯托夫•亚历山大(Christopher Alexander)的《模式语言》(A pattern Language)一书,这是一本建筑学方面的著作,这本书影响一代又一代的建筑设计师,但是在计算机科学界有着非常深远的影响,文中所提出的模式一词已经被广为引用,并已远远超出了原来的领域,成为许多人一直在追求的普遍性原则。书中模式概念的定义是:在某一个情景下的问题解决方案,如果问题的环境相似,那么对问题的解决方案可以重复应用,可以重复应用就是它们存在的理由和价值。分析模式一书的作者Martin Fowler认为,模式是一种思想,它已经适用于一个实践环境中,并有可能适用于其他的环境。(A pattern is an idea that has been useful in one practical context and will probably be useful in others.)
1、概述
在一个大型的企业应用的设计过程中,设计师绞尽脑汁,总是希望设计出来的系统更符合要求,更具扩展性和先进性。但这是其中的一部分,也就是设计师如何更好的设计系统还需要很多已成熟的技术的支持,对了,那就是别人经验的积累,充分的利用可用的、成熟的设计技术也是系统设计过程中很重要的一部分。
本文的目的是介绍一种数据库传输设计的模式,它的来源是我参与国外的一些系统开发之后总结出来的一种基本模式,我总结了这个一些设计,形成一种基本的DTO模式,并不断的修改(不存在版权问题)。我觉得时机已经到了,可以公开了的时候了。但是我在写这篇文章之前还是有些当心,担心我所要描述的设计是不是前人已经做了很不错的设计了,这样一来,我又是片面的说明一种问题,又是瞎扯什么H-DTO,而且还涉及到模式,我不敢再想下去。后来我想通了,我只是一个知识浅薄的开发人员而已,手头上空出的时间写写不起作用的文章也是无防吗。
本文虽然是用java实现设计过程,但是对于支持面向对象的环境都是支持的,因为Hash表是数学和计算机领域的一个基本概念,也是数据结构中一种常用的数据组织和表达方式,只要你的语言环境可以支持面向对象和Hash或是类似的都可以实现这个设计。
该模式实现的目标是:实现层次间(比如MVC模式的控制层和模型层、表示层与控制层)、对象间(比如一个控制类和一个显示页面)数据的有效传输和管理;在Web应用中可以结合Session实现数据的有效转移;在普通应用中可以实现数据合理组织和分发。
2、简单测试类的分析
下表是一个H-DTO模式的测试类,很简单,但是你可以仔细的看看,里面那些对象是比较有特色的。我们通过一个测试类分析入口。
TestFormData.java
/*
* Created on 2004-7-2 by Jem.Lee
* TestFormData.java is a part of com.test
* ALL RIGHTS RESERVED.
* COPYRIGHT (C) 2004. Jem
*/
package com.test;
import cn.bs.common.transdata.TransFormData;
import cn.bs.common.transdata.TransFormTable;
/**
* <PRE>
* History
* 2004-7-2 22:46:54 created by Jem.Lee
*
* 目的
* 测试H-DTO模式
* </PRE>
*/
public class TestFormData {
public static void main(String[] args) throws Exception {
//申明TransFormData对象
TransFormData sesData = new TransFormData();
//向TransFormData对象(sesData)放置数据
sesData.putFieldValueO("Test1","Test1Value");
sesData.putFieldValueO("Test2","Test2Value");
sesData.putFieldValueO("Test3","Test3Value");
sesData.putFieldValueO("Test4","Test4Value");
//从TransFormData对象(sesData)取得数据
System.out.println(sesData.getFieldValue("Test1"));
System.out.println(sesData.getFieldValue("Test2"));
System.out.println(sesData.getFieldValue("Test3"));
System.out.println(sesData.getFieldValue("Test4"));
//向TransFormData增加一张表
TransFormTable table = sesData.addTable("MyTable");
for(int i = 0; i < 10; i ++){ //10 rows
//向表增加一条记录
TransFormData data = table.add(); //5 counlums
//往记录里面添加Field,并设值
data.putFieldValueO("tableCoun1","01");
data.putFieldValueO("tableCoun2","02");
data.putFieldValueO("tableCoun3","03");
data.putFieldValueO("tableCoun4","04");
data.putFieldValueO("tableCoun5","05");
}
System.out.println("-------------------table1----------------------");
for(int i = 0; i < 10; i ++){
//从表中获得一条记录
TransFormData rec = table.get(i);
//获得记录的每个field的值
System.out.print(rec.getFieldFromName("tableCoun1").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("tableCoun2").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("tableCoun3").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("tableCoun4").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("tableCoun5").getValue());
System.out.println("|");
}
TransFormTable table2 = null;
int tableSize = 0;
//向TransFormData对象增加一个表,
//并判断该表是否存在,如果存在,则获取该表的对象,否则创建表
try{
table2 = sesData.addTable("MyTable");
}catch(Exception ex){
table2 = sesData.getTable("MyTable");
tableSize = table2.size();
}
for(int i = 0; i < tableSize; i ++){ //5 rows
TransFormData data = null;
//向表中增加记录,并判断该记录是否存在,
//如果存在,则获取该记录的对象,否则创建记录
try{
data = table2.add(); //5 counlums
}catch(Exception ex){
data = table2.get(i);
}
data.putFieldValueO("table2Coun1","01");
data.putFieldValueO("table2Coun2","02");
data.putFieldValueO("table2Coun3","03");
data.putFieldValueO("table2Coun4","04");
data.putFieldValueO("table2Coun5","05");
}
System.out.println("----------------table2---------------------");
for(int i = 10; i < 20; i ++){
TransFormData rec = table2.get(i);
System.out.print(rec.getFieldFromName("table2Coun1").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("table2Coun2").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("table2Coun3").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("table2Coun4").getValue());
System.out.print("|");
System.out.print(rec.getFieldFromName("table2Coun5").getValue());
System.out.println("|");
}
}
}
运行结果是:
Test1Value
Test2Value
Test3Value
Test4Value
----------------------table1------------------------------
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
--------------------------table2--------------------------
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
01|02|03|04|05|
通过文件中的注释可以明白个大概,其实整个文件就是用到两个主要的对象:
import cn.bs.common.transdata.TransFormData;
import cn.bs.common.transdata.TransFormTable;
这就是H-DTO的主要成员,一个是装载数据对象,一个是表对象。他们之间的关系是:
TransFormData可能包含多个TransFormTable
TransFormTable可能包含多个TransFormData
看起来似乎是没有规则,但是仔细看程序就会知道:
TransFormData是应用的入口,当作一个总的数据对象,其中容纳多个表(TransFormTable)和多个Field(TransFormField),TransFormTable又可以创建记录(TransFormRecord),记录的表示也是通过TransFormData,所以TransFormData与TransFormRecord又内在的联系。后文会提及。
文中提到的:TransFormData、TransFormTable、TransFormField、TransFormRecord构成了H-DTO的主要枝干。
3、UML设计
下文描述H-DTO的UML类模型,说明他们之间的连带关系和设计思路。相信通过UML类模型,绝大部分开发人员已经明白大致怎么回事了,甚至可以自己看是动手做一个东西出来。
ClassDiaram
ComponentDiagram
<待续>第一部分介绍到这里,第二部分将介绍如何在Java平台上实现这些设计。希望你多多来信探讨设计。