我的”框架”之数据域
 

2010-04-07 作者:xiyang1011 来源:xiyang1011的blog

 

已经很久没有写这个系列的了,距离上一篇好像快半年了。回首看看已前写的东西,真是有些幼稚,很高兴有人还会去看并评论,在此谢谢大家。前几天看了下金色海洋写的一篇文章,感觉一意犹未尽,自己也写了一篇,在此献丑了。

这篇文章相当于一个总结,也可以说是一种新的理解,我也在尝试。废话不多说,进入正题。首先还是要对一些名词解释下。

名词解释

数据域:无论是CS结构或BS结构的软件,页面都会用于展示和维护数据操作,比如:新增、修改、删除等。每个页面会有若干个数据模块,比如列表页面,一般只有一个grid网格控件,批量展示数据使用这就相当于一个数据域;也可能还有一个树控件,用于分组显示使用,这也可以看作一个数据域。还有单据页面,主明细表(2个数据域),主表+4个tab页(5个数据域)。

业务场景

一个页面/窗体,其实都是对数据进行操作,包括新增、删除、修改等。有的页面,可能新增操作就会有好几个,比如HIS软件中,检验模块列表,可能有检验新增和检查新增,如果把这两个操作比作两个类的话,那它们之间藕合的可能性很小,可能是两个密封类。但它们之间又有很多共性的东西,比如都是对数据进行新增等。如何将它们之间的共性和个性区分开来呢。这里我们就要引入第三个类了,这也是一般解藕的方法,把共性的东西放在第三个类里,然后共同引用。

数据域的作用就是把这些操作整合出来,封装成一个单独的类来管理这些。

数据域操作

下面是一个数据域所有完成的操作,可能概括不全。

  • 主要操作

1. 加载数据并绑定到控件:获取dataset或datatable对象,绑定到grid等展示性控件。

2. 数据操作,执行新增、修改、删除等操作,还包括一些功能操作(根据名称获取其拼音输入码填充到拼音码栏目中)。在此期间,还进行简单的检测,例:必输字段是否为空等。这是界面层要处理的事情。

3. 数据操作完成以后,还需要填充一些UI层不需要填充,但又必须填充的栏目值,如:ID流水号、创建人、创建时间等

4. 数据保存检测,包括数据正确性检测(栏目值是否符合栏目类型)、数据准确性检测(栏目值符合自定义的规则,例:单据日期不允许超过本月底等)、数据重复性检测等;

数据删除检测,需要检验数据引用关系。

5. 业务检测,真正的行业业务检测,直接继承接口即可。这部分将是以后操作的重点,因为它涉及到一个行业的业务需求,不是一年两年就能搞清楚的。

6. 获取与保存时生成的同步sql语句。这句话有这样一个业务场景:主明细单据保存时,明细表数据可能先全部删除掉,再全部执行新增操作。这个操作就是获取delete from table_detail where danjuid = xxx这条sql语句。

7. 获取数据同步sql语法。这句话有这样一个业务场景:一个单据新增的时候,可能会同步触发另外一个模块的新增操作。这个操作就是获取该操作的sql语法

8. 获取该模块的sql语法,用于保存

9. 数据真正保存,批量执行sql语句,使用事务。

上述的操作过程,是数据从数据库里提取出来展示给用户,用户浏览并对数据操作,最后回填给数据库的过程。我的想法是,开发员只需要关注两部分内容即可:一部分是UI层的数据绑定Db字段值和保存前的数据收集。另一部分是行业业务层的操作。

程序分层

  • 数据层

这个没什么好说的,就是封装了一些与Db操作有关的方法集,例:保存时使用事务之类的。

  • UI控件层

这里我创建了三个项目,如图-1所示

图-1

其中,Navi.Kernel.UILayer项目是Webform和Winform控件所用到的通用方法,比如权限及各种控件参数的定义。

Navi.Kernel.UILayer.WebControls是Webform控件集,由于才开始接触,没封装很多。针对各种类型的方法,我们将它们分门别类的放在几个类文件里,然后由pageBase统一调用它们的接口,如图-2所示。

图-2

Navi.Kerncel.UILayer.WinConrols是Winform控件集,封装了一些常用的控件。

  • Service层

这层主要用来收集各种方法,比如:针对字符串、日期、文件、Db操作等,如图-3和图-4所示,创建了两个项目,分别用来加载接口和实体类。

图-3

图-4

使用这些方法的时候,我使用的是单例构造模式,如图-5所示

图-5

  • Model层

这个要详细说一下。在我的整个程序中,Model层是非常重要的一层,因为它贯穿整个程序,起着承上启下的作用。Model层包含两个子类,分别是Winform和Webform,分别对应CS和BS软件。

一方面它负责调用Db层、Service层的各个方法,相当于一个集合,如图-6和图-7所示

图-6

图-7

另一方面,UI层中会有很多模块,以His软件来说,会有检验单和检查单等。我会为它们分配一个Model文件,用于辅助UI层操作。

Model层中包括很多方法,上面描述的“数据域操作”的步骤中,加载数据、数据保存、数据删除等。如图-8所示

这是一个模块的列表页面,如果我们想要从Db中读取数据出来,并加载到指定的控件(不一定是Grid控件的)。首先我们创建一个类,继承自BaseModel类,如图-9所示

然后,我们只需在这个类的构造函数中配置若干信息即可,如图-10和11所示

图-10

图-11

在上面的图片中,AuthorID系列的属性是确定该模块的模块ID,整个系统中识别该模块的唯一变量,独一无二;ListEventLevel是定义列表页面工具栏按钮事件级别的,事件分为三个级别:祖先级别,所有模块均可以使用、模块级别,只被这个模块使用。自定义级别,即写在行业业务级别(可以针对不同的行业业务自行编码)。

ListMaster系列的属性,就是定义一个数据域所需要的各种参数,如:Sql语句、数据域所对应的Db表,数据存储位置(包括数据库和Xml文件),如果数据域有数据操作,还需要定义是否启用主键并设置如何获取主键。这里没有所谓的insert或update语句,是因为在提交数据库的时候,会根据行状态,自动生成insert或update语句,同时使用lognet生成日志,方便查看。图11的部分是设置附加属性,如grid控件的列标题等。

通过上述属性设置后,模块的非UI部分已基本完成,下面我们再看看UI层本身要做什么事情?如图-12所示

图-12

声明一个Mode层只属于该模块的文件。

首先加载页面标题,然后,加载工具栏数据(可以自行配置,也可以通过权限设置,确定按钮是否显示和可用,可精确到个人),最后,加载List.Master数据域数据,使用grid控件展示。

通过Model层的使用,UI层的压力减轻不少,只需调用Model层中已经配置好的属性即可,是不是很简单咯!我们再看看数据保存的部分,如图-13所示

图-13

它包含数据收集,数据验证和数据保存三个部分。UI层要做的事情就是收集数据,验证部分是通过配置文件完成,如:是否重复、数据准确等,当然,某些特殊的验证还是要自己写的,配置文件只负责常规的验证。如图-14所示

图-14

  • Common层

这个层一般用来编写比较通用的功能,例:查找、高级检索、定位、统计等,如图-15所示。

图-15

以“查找”功能来说,也是创建一个类文件,继承自BaseModel类(因为它是Service的方法集合,相当于代理),在类文件中调用打开frmFind页面的方法,如图-16所示

图-16

我们在业务模块使用“查找”功能的时候,只需要这样编写代码即可,如图-17所示

图-17

  • Business层

这个层之所以放在最后说,是因为它即重要又不重要。说重要,是因为它是整个系统的血肉,如果没有它,整个框架就是一堆骨架,没有任何作用,是它来填充系统的业务功能;说不重要,是因为它只需要继承Service层中某些接口即可。如前面所说的,我们想重写新增操作,写在这里即可。如图-18所示,也是一个模块对应一个Business层文件

图-18



使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   


.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield


日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...   
 
 
 
 
 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号