Tiger_Zhao对树类早期设计的点评及数据一次性载入的方案

本文通过实例探讨了数据库对象设计中的常见问题,如集合与成员的关系处理、数据一次性加载策略等,并提出了一种面向对象的设计思路,以提高数据处理效率。

版权声明:可以任意转载,转载时请务必以超链接形式标明如下文章原始出处和作者信息及本声明

作者:xixi

出处:http://blog.youkuaiyun.com/slowgrace/archive/2009/04/20/4095485.aspx

本帖来自与Tiger_Zhao讨论,感谢Tiger_Zhao这个帖子里比较详细地分析了早期设计的各种问题,这里摘录一些对我有启发的结论:

(1)其实你最大的问题是没有区分数据结构中集合和成员的关系!

比如对任意一个数据库表,在.Net 中至少有两个主要数据对象 DataTable 和 DataRow。对应到通常对象设计中,两个对象都可以实现业务规则,通常成组操作要的业务在集合类中实现,而单记录的业务规则在成员类中实现。有时候成员如果只是简单的数据存取,利用RecordSet可以省略成员类,所有业务规则全部在集合类中实现。这时候集合类可能不需要设计为一个集合,这时可以将它称为管理类。如果业务复杂,就应该细分设计,比如:

(2)数据一次性载入的方案

CAnnaDetail 或 CAnnaTree 一次性载入一个数据表,读信息就直接在对象模型中操着,写信息就同步更改到数据库(貌似和下面的设计不符,西西注),只需要在最外层用事务保证数据一致性就可以了。

只要在成员类中加一个私有的状态标志(你可以直接用 ADODB.RecordStatusEnum,其实只需要 New、Modified、Unmodified 三种值)

(3)你还是在用过程的方式在设计!你的需求换成 OO 方式应该是如下调用的

(4)关于数据库存取方案的讨论:一次性载入是最快的

西西:感觉您还是不折不扣地推荐把所有的数据读入内存,直到用户点击save,再和数据库打交道。我是想CTree并不保存数据,它只是用来从数据库读东西、写东西。

zhao:将集合类看成 RecordSet,成员类看成 RecordSet 的 1 行。虽然的确可以通过简单地对 RecordSet 的封装实现数据库更新,但是 RecordSet 的内存耗用通常比纯数据大1个数量级,最好用成员类保存属性。

西西:我在生成树时都不是一次性地全load的,而是只生成到当前展开的节点的孩子节点那一层,底下的随时展开随时从数据库读入。所以,更新数据我也都是实时写到数据库里的。这样万一有别的树控件也用到这个表,但是相应的节点还没展开,就能读到最新的数据。我现在好像基本倾向于这样了。一个CTreeCtl类用来展示,也保存它已经展示了的节点的数据;一个CTree类用来和树表打交道。

zhao:TreeView 控件展开时加载,这是很好的方案。但是数据库分次读取就不划算了,这反而影响了展开时加载的速度。一次性加载,在内存对象中遍历节点是最快速的。CTreeCtl 不需要保存任何数据,已显示的节点在 TreeView 中有足够的信息(其实只要能取得 ID 就够了)。CTree 只保存节点关系,真正的节点信息保存在 CDetailList 中(独一份),你只要将数据的刷新用事件通知到各个 CTreeCtl,那么所有的 TreeView 都是最新的、同步的。

更多树类文章

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值