开场白
面向过程:面向过程是“写代码”,根据客户提出来的需求来写代码,包括函数。一步一步的写,都写完了,功能也就实现了。
面向对象:面向对象是“做设计”,先不考虑细节,而是先做总体设计。都设计好了,再去实现细节。
举例来说,面向对象是设计一部汽车,而面向过程是设计一个流水线生产汽车。设计一部汽车是要考虑客户的需求,考虑众多因素,然后画图纸。并不考虑到底如何把汽车生产出来(至少不是重点)。流水线的目的呢,就是要把汽车生产出来,至于汽车是如何设计的并不关心。
以前“自然框架”就是按照面向过程的思路来实现的(因为当时只会面向过程),虽然功能实现了,想要达到的目的也基本完成了,但是自己也说不明白,给人的感觉就是雾里看花,没有一个整体的印象。原因很简单——没有按照面向对象的方式做总体设计。
一个想法要想生存的更长久,那么就必须能够得到更多人的认可。那么首相就要能够让更多的人能够了解,都不了解呢怎么可能得到认可呢?
而一个框架想要更强大那么就必须能吸引更多人的加入,一个人的能力毕竟是有限的,众人拾柴火焰高。那么前提条件还是能够让更多人了解,了解框架的基本思路、各种强大的功能。
所以最近这些日子又重新设计了一下,重新考虑整理,在逐步整理的过程中也了解到了MVC的意图。
自然框架的说明
一、 目的
针对增删改查密集型的项目,做到快速开发、快速维护的目的。
企业定制开发的项目效果更显著!
二、 特点之一:摆脱“拖拽控件”的烦恼!
什么?您说拖拽控件很简单?!I服了U。如果一个表单有50个控件(字段),那么要拖拽50次,然后要做设置,不管你是用向导还是后台写代码,都是要设置一下的对吧。控件的宽度、高度,文本框的最大字符数,下拉列表框的Item的设置,控件和字段的对应等等。而这样的表单有多少呢?10个、50个、100个?项目越大数量也就越多。有的表单要单列,有的要双列,有的要合并TD。更有甚者一开始要单列,后来觉得宽度上有点浪费,要改成双列,但是改成双列后看着还不如单列顺眼,于是又让你改回去!
那么一个项目做完了要拖拽多少次?如果客户的需求有了变化,又要改多少次?这就是我所说的烦恼!
自然框架的第一个目的就是要摆脱这些烦恼,单列、双列?设置属性即可。宽度、高度、最大字符数、Item的填充,这些统统的都是设置属性,简单方便,而且还有一个配套的程序(配置信息管理程序)来辅助修改这些属性。那么是如何实现的呢?请看下面的说明。
这个看起来有点像MVC,我对MVC也不太了解,虽然看了《深入浅出设计模式》,但还是比较模糊,所以这里就不往MVC上面套用了。
自定义控件可以理解为UI,也可以理解为View。它包括分页控件、表单控件、查询控件、数据显示控件、操作按钮组、流程按钮组等。这些控件的特点就是不需要在代码里做详细的设置,而是根据“元数据”自动绘制。
把“数据显示控件”和GridView做一下对比:GridView需要在.aspx页面里面设置第一列显示哪个字段的内容,第二列显示哪个字段的内容…… ,然后在后台设置数据源、绑定控件。每一次使用GridView的时候都需要做类似的设置,这样做就很麻烦了(至少我认为是比较麻烦,呵呵)。而“数据显示控件”不需要做这些设置,他是根据“元数据”的内容来自动绘制的。而元数据也不是在代码里面设定的,而是存放在了一个容器里面,需要的时候(也就是运行的时候)才提取出来,供“数据显示控件”使用。
这样做的优点就是可以在运行时决定显示什么样的数据,也就是说当客户的需求有变化的时候根本不用修改代码,更不用重新编译,只需要修改一下“元数据”就可以了。
“模型”:里面存放的是“元数据”,也就是“配置信息”。
元数据对于自然框架来说是很重要的,就好比音乐文件之于MP3播放器;子弹之于枪支。没有音乐文件MP3播放器能做什么?没有子弹,枪就是一块废铁。如果没有元数据,那么自然框架也就是一大堆控件、类库的集合体。元数据让控件活了起来,把各个部分有机的结合在一起,发挥强大的功能!
“元数据”的作用是要对字段、控件进行描述和对应。结构图如下:
【图一:字段和控件】
【图二:控件的特殊信息】
【图三:功能模块的信息】
ORM里面是把实体类和表对应起来,把类和表作为同一级别,属性和字段作为同一级别。最小单位是表,字段是不能独立存在的,也不能够拆分重组。这是一只困扰我的问题,我觉得如果能够把字段作为最小单位,让他们可以灵活的拆分组合,需要哪些字段就把哪些字段组合在一起,这样就简单多了,延迟加载也就完全没有必要了。
所以在自然框架里面字段是最小单位,字段和类是同一级别,而表只是字段的一个“标识”,标识一下这个字段是哪个表的,遇到相同的字段名区分一下而已。然后根据需要把字段集合起来。比如一个小模块的列表页面需要字段1、字段2,那么就把这两个字段放在字典(Dictionary)里面,以供使用。这样就很灵活了。
而字段和控件的对应则采用父类和子类的方式来对应的。字段信息作为父类,控件信息作为子类。根据环境分为了三类:添加/修改、查询、数据列表。于是就有了图一。
控件是各种各样的,属性也是五花八门的,有一部分是相同的,那么就按照分类变成了图一里的三个类的属性。但是有些属性是很不相同的,那么怎么办呢?没办法又定义了一套类,于是有了图二里的几个类。
ColumnsInfo就是对字段的描述;FormInfo是对表单的描述,就是表单控件和表单控件里的布局的描述,包括添加、修改的表单,和查询功能的表单,ModInfo就添加、修改里用的信息,FindInfo是查询需要的信息。合起来就是字段和控件的对应关系。ORM说的是实体类和关系(表)的对应,而我这里要做的是字段和控件直接对应起来。
ORM是用实体类与XML或者实体类与特性来实现对应的,我这里完全采用类的属性来做对应。这样做的优点就是避免了“类爆炸”,把类爆炸换成了“实例爆炸”。实体类是随着功能的增加而增加,再怎么抽象也是难以限制数量。
而这里种类就是一个,功能再多,表再多,类的种类就是这样的,不会随之增加,增加的是实例,这样就很方便管理了。
“容器”:上面说的其实是内存里的容器,内存里的数据是不能永久保存的,断电就没有了,所以要找一个能够永久保存的容器。可能您想到的是XML,但是我想到的是关系型数据库。为什么用关系型数据库呢?因为我可以利用“关系”来避免冗余,提高利用率。同一个表里的同一个字段,可能在多个地点(比如表单、查询、列表,另一个页面的查询、表单、列表)出现,需要多次出现的怎么办?字段名、字段大小、类型,甚至是对应的控件都是一致的,怎么能够避免这种“重复”(即冗余)呢?用关系型数据库里的关系来解决就很容易了。数据结构如下:(是不是有点眼熟,对,在前面的“通用权限”里面就提到过。)
这个结构和上面的类的结构是对应的,但是他们却不是一一对应的。类的设计是按照类型、结构来设计的,同类的放在一起,其他的放在另一个类里面。而数据库设计是按照数据的异同来设计的。同样的数据放在一起,不一样的放在另一个表里面。
所以就导致了类和表没有一一对应的结果。
管理:这里没有用MVC里的“控制”,因为我感觉这个和“控制”还不太一样,所以用“管理”这个词,避免混淆。控件也好,模型也好,添加数据的功能也罢,他们是怎么配合的,又是怎么工作的?这就由“管理”来全权负责了。
“管理”是一个黏合剂,他把控件、元数据、容器、提取数据、保存数据、查询数据等粘合在一起。这个也就是MVC里的C的作用。当然了和MVC还不大一样,只是有点“神似”罢了。
“管理”首先从容器里面把配置信息提取出来放到“元数据”里,并且缓存起来(Cache),然后把元数据设置给控件,控件就可以根据配置信息来绘制表单了。
当用户点击“保存”等按钮的时候,就会通知“管理”启动保存数据的“进程”,依据元数据(配置信息)来拼接参数化的存储过程,生成存储过程的参数,最后调用“数据访问函数库”实现保存数据的功能。
三、 特点二:摆脱“拼接SQL语句”、设置存储过程参数、取值赋值的烦恼!
不管您使用SQL语句、参数化SQL语句,还是存储过程,还是linQ to SQL ,都需要拼接字符串,当然了存储过程和linQ to SQL是直接写,虽然没有拼接但是还是要写呀。而且保存数据(添加、修改)的时候还需要把控件里的值(就是用户输入的信息)提取出来,对了还要做验证。我很懒,我觉得这些都很麻烦,我知道有“代码生成器”这个东东,但是他是治标不治本,只能更快的生成代码,而不能根本上解决这个烦恼。
不用写直接就出来了该多好呀,另外一点就是,如果需求有变化了,应对起来也要非常容易才行,不能改一个小地方比整个重做一遍还难,这是绝对不行的哦。
最半边是显示数据,右半边是添加、修改数据。可以根据元数据来拼接参数化SQL语句,并且生成需要的存储过程的参数。这些都是根据元数据自动运行的,不需要根据不同的功能而作修改,只需要修改元数据就可以了。而元数据本质上就是记录,对元数据的维护就相当于对记录的增删改查,恩又绕回来了。
========================================
【视频】配置信息管理 的 使用方法(一):数据库文档(Excel)的格式说明 (2009-11-26 18:28) |
【视频】配置信息管理 的 使用方法(二):建表、添加元数据 (2009-11-27 18:15) |
【视频】配置信息管理 的 使用方法(三):查看和修改元数据、查看数据库的表视图存储过程等信息 (2009-11-27 20:09) |
【视频】配置信息管理 的 使用方法(四):功能节点维护 (2009-11-27 21:50) |
【视频】配置信息管理 的 使用方法(五):配置程序之列表、分页控件、按钮 (2009-11-27 23:04) |
【视频】配置信息管理 的 使用方法(六):实现添加、修改、查询 (2009-11-28 08:31) |