BearOcean

Say HelloWorld
随笔 - 19, 文章 - 0, 评论 - 149, 引用 - 3
数据加载中……

解决站点关键数据,状态数据,无须持久化数据的一些思路

BssCriticalCompiler 设计说明(草案)(概设)
-解决站点关键数据,状态数据,无须持久化数据的一些思路 
                      bearocean 2008-06-04




1. 关键数据(CriticalData) 的定义 
2. BSSCriticalCompiler 
2.1. 基本思路/设计目标 
2.1.1. CriticalData 集中定义 
2.1.2. 基于XML 的描述 
2.1.3. 同时支持编译时和运行时策略 
3. 结语



 

1. 关键数据(CriticalData) 的定义
站点系统中通常会出现一些改动不大的数据项。
这些数据不会经常改动的原因在于:
(1) 这类型数据本身在需求中不要求修改。
(2) 这类型数据大规模参与了系统逻辑,修改将导致系统中大规模重构,当要对这类型数据项进行修改时,会导致从页面(View) 到Controller 到逻辑层,最后到数据库中的过往数据,均要求rebuild。

通常我们从这类数据中提取出2个关键属性: DisplayName, Value,实际上有枚举或者键值对的意思。
这类数据的常见例子:
性别信息, 如:
DisplayName: 男 Value: 1 (即表示显示层显示男, 内部逻辑和数据库中,我们通常存放1表示一个用户为男性)
DisplayName: 女 Value: 2

国家/地区信息, 如:
DisplayName: 中国 Value: 1
DisplayName: 美国 Value: 2
DisplayName: 法国 Value: 3
….

状态信息, 如一个用户的状态我们可以表示为:
DisplayName: 开通 Value: 1
DisplayName: 暂停 Value: 2
DisplayName: 关闭 Value: 3
….


这种数据在系统中常常被硬编码,如
显示层,我们在用户注册页面会出现如下代码:

1<input type=”select”>
2 <option value=”1”></option>
3 <option value=”2”></option>
4</input>

用户编辑页面也会出现这样的代码。

对于状态信息,我们常见的逻辑编码会出现这样的代码

1if(User.State ==1){
2  //用户状态为开通,执行逻辑
3}
else if(User.State ==2){
4  //用户状态为暂停,先开通
5}
else if(User.State ==3){
6//禁止执行逻辑
7}
。。。

对于国家地区类数据,我们常常把他们存放于数据库。
但是如果没有对国家地区类数据进行 修改/添加/删除的必要,实际上这种数据也没有太大的必要存放于数据库中。

总的来说,这类型数据(特别是状态码) 通常是整个系统的关键支撑。
对于实践过程,我们通常不推崇修改这类型数据。
设想,系统中,过去表示用户开通状态的编码在数据库中为(int)1 , 在页面上显示为”开通”。
但是如果我们出现需求(姑且不论这个需求是否合理) 要求开通的编码用2表示, 在页面上不再显示开通, 而显”正常运行”。那么我们要修改哪些地方:

显示用户信息的所有页面
用户添加页面
用户状态修改页面
修改用户状态的编码逻辑(开通逻辑将改为设置用户状态为2)
过去已存储的用户数据 1->2
….

这是一个噩梦。
如果不提及对于这类数据的修改。
只考虑添加一种新的状态: DisplayName: 欠费 Value =4 (系统总是会扩展的)
那么我们发现需要修改的部分有:
用户添加页面
用户编辑页面
修改用户状态的编码逻辑(添加欠费相关逻辑)
….

仍然是噩梦,而且在进行代码修改的时候,凭借开发者的记忆,怎样能确保所有相关的修改都已经完成,例如我们可能会忽略某一个页面的修改。

过去曾经有一个记忆深刻的教训
我们在开发一个HR站点的时候,由于学历类型相对比较固定,所以在系统中硬编码了学历数据。
类似于:

 1<input type=”select” name=”education” id=”education”>
 2  <option value=”1”>中专</option>
 3  <option value=”2”>职高</option>
 4  <option value=”3”>技校</option>
 5  <option value=”4”>大专</option>
 6  <option value=”5”>本科</option>
 7  <option value=”6”>本科双学士</option>
 8  <option value=”7”>硕士</option>
 9  。。。。。
10  <option value=”10”>博士</option>
11</input>

这样的代码分布在十多个页面中。
后来客户提出要添加一项 “value =11 博士后” 的时候, 我们开始找这十多个页面。实际上,可想而知,这是非常的痛苦的。

这类型的数据没有统一的定义。我们姑且将其定义为关键数据(CriticalData)
关键数据在Web系统中通常有这样一些特性:
a) 不需要存储于数据库中。
b) 通常大量参与逻辑
c) 虽然通常不变,但要进行修改/添加 的时候会非常麻烦。
e) 在代码中的表现方式通常是: 硬编码/ 或者静态变量。


2. BSSCriticalCompiler

开发BSSCriticalCompiler 主要是提出一种思路,来解决上述的问题。
从而增强系统得可扩展性,使代码更为优雅。

2.1. 基本思路/设计目标
2.1.1. CriticalData 集中定义

如上述章节所描述的。
系统的关键数据定义通常分布于系统各个地方,这是导致扩展性降低的原因。
希望能有一种方法把关键数据的定义集中化。


2.1.2. 基于XML 的描述
开发人员在对Critical进行定义的时候,不需要进行直接代码开发,而是编写一组更易于阅读的XML 文件。由这组XML 文件对关键数据进行定义和描述。具体的编码转换或者运行时依赖由BssCriticalCompiler 完成。
该XML描述文件与下列文件类似:

1<?xml version="1.0" encoding="utf-8"?>
2<dataset id=”sex”>
3  <item displayname="女" value="1" type="int" />
4  <item displayname="男" value="2" type="int"/>
5</dataset >

2.1.3. 同时支持编译时和运行时策略
2.1.3.1. 编译时策略

编译时策略的种体思想类似于MDD (Model Driven Development)
具体过程如下图所示:
 
使用方式为 开发人员 定义XML 关键数据定义文件。
其后调用CriticalCompiler 将XML 关键数据定义文件转换为一种较为合理,调用方便的关键数据定义源代码。(Java 中初步考虑的是一组包含静态变量的接口).
开发人员在系统中对该生成的CriticalData 定义进行依赖。尽可能避免硬编码。
如果需求发生变更,重复上述过程。
2.1.3.2. 运行时策略
运行时体系结构作为另外一种可选策略受支持。相对于编译时策略,XML定义文件和解析过程完全一致。但是不同的地方在于CriticalCompiler对XML 解析/编译在网站运行时(具体应该是网站startup的时间) 并且不会生成源代码。 开发者的代码可以同过对CriticalComiler RunTime Lib 的依赖对关键数据进行引用。
最大的优点在于,修改XML 并不需要重新编译整个项目。只需要重新将XML 文件部署到合适的文件夹路径,并重新启动Web服务。
如下图所示:
 
3. 结语:
总的来说,该模型非常简单,主要目的在于集中控制关键数据,增强代码的扩展性和可维护性,作为关键数据定义的XML 文档,即可以作为源代码的一部分(元数据).也可以作为文档存在。
通过这种思想来实现该Lib 是否能真正的降低Web 修改时造成的重构成本。还不能够确定。目前主要作为一种设计/实践 思路来应对。
基于Java 的CT RT 模块预计本周可以完成模型。
另外该文档不涉及BssCriticalComiler 的调用说明,只作为思路阐述文档和概设存在。

                                                                                                                bearocean 2008-06-04
我发现 cnblogs 比csdn的blog好用。。。但是我很久没做.net 了。

posted on 2008-06-04 15:01 BearOcean 阅读(2025) 评论(12)  编辑 收藏 所属分类: 设计模式BlueSources

评论

#1楼    回复  引用  查看    

为什么不用枚举呢?
2008-06-04 15:41 | lazylu      

#2楼 [楼主]   回复  引用  查看    

@lazylu

可以用枚举阿。用枚举是比较好。
不过枚举也会分布在代码不同的地方。
我现在在想能不能把这些枚举都集中到xml 文件里,然后再分编译时/运行时 去引用。
如果是编译时, 就依据xml 生成集中的枚举定义,然后放置到源代码中。
如果是运行时, 就用其他办法。但是Xml 可以重用, 解析部分的代码也可以重用。

只是一个思路。 :)
2008-06-04 16:00 | BearOcean      

#3楼    回复  引用  查看    

如果是多域名站点的话,如果修改了XML数据,每个站点的XML都得更新,也麻烦.

一般情况下,他们不能共用.
2008-06-04 17:51 | xj      

#4楼    回复  引用  查看    

一个不错的思路。。。
2008-06-04 18:09 | sishuiyitan      

#5楼    回复  引用    

@xj
存到数据库里, 再编译就可以了
2008-06-04 18:35 | zhengxionghua [未注册用户]

#6楼    回复  引用  查看    

不至于这么大费周章吧。

不考虑效率的情况下,直接放在数据库里,然后读取就可以了。

想减少硬盘的读取的话,放在内存里缓存就可以了呀。

你这么处理的优点是什么呢?
2008-06-04 19:09 | 金色海洋(jyk)      

#7楼    回复  引用  查看    

好像和asp.net里面的buildprovider很像阿?能够提供设计时支持。
2008-06-04 22:39 | BAsil      

#8楼    回复  引用  查看    

还是放在数据库里比较好,用类似代码生成的方式生成一个里面有很多枚举类型的项目,各个需要用到的项目或者站点引用这个项目就可以了,数据更改后重新生成该项目。
2008-06-05 09:21 | 小庄      

#9楼    回复  引用    

可以做一个公共的数据库,然后各相关项目统一读取。读取完之后各项目进行缓存。
2008-06-05 14:29 | oldmoon [未注册用户]

#10楼 [楼主]   回复  引用  查看    

@oldmoon
不错,是个好办法。不过我还是要按照我的思路来写一下,然后用到自己的WEB里面。:)
2008-06-05 16:23 | BearOcean      

#11楼    回复  引用    

一篇好文,怎么被淹没了?
我就常常碰见搂主说的问题。其实什么东西都可以放到数据库解决,但是访问量以10万递增时,一个bit字段你都想省略掉。。
不过假如以xml为基准,省份城市,至少有上千个displayname和 value了,估计性能也不佳。
期盼早日看到实现代码。
2008-06-06 14:39 | reddust [未注册用户]

#12楼    回复  引用    

一个对象的xml序列化和反序列化,搞的这么复杂,弄这么多图。
@楼上,性能根本不成问题
2008-06-08 00:37 | wyrover [未注册用户]

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-04 15:06 编辑过


相关链接: