[转载]设计架构优秀的 Framework

[转载]设计架构优秀的 Framework – 兼谈 ORM Framework – Riceball LEE – 博客园.

本文只是自己在实际架构Framework积累的微薄的经验,如有谬误请大侠专家不吝赐教为盼。
架构设计是一种权衡和取舍。一个Framework是为了解决某一个领域内的某些问题的代码复用而因运而生的,而问题总是有多种的解决方案的。而 我们要确定唯一的架构设计的解决方案,就意味着我们要在不同的矛盾体之间做出一个取舍。我们在设计的过程总是可以看到很多的矛盾体:开放和整合,一致性和 特殊化等等。任何一对矛盾体都源于我们对Framework的不同期望,需要我们在各种方案中作出不同的取舍。没有一个Framework能够满足所有的 要求,只是架构的侧重不同。而一个设计优秀的 Framework 则是体现在其架构简单明了,层次分明,重用价值高;运行高效率,稳定(完善的TDD测试机制)。

一个架构优秀的 Framework,至少要满足以下的特征:
* 重用:为了避免重复劳动,为了降低成本,我们希望能够重用之前的代码、之前的设计。重用是 Framework 实现中最为核心的目标,重心中的重心。提高复用度是Framework的首要目标。
* 层次分明,高度部件(组件)化: 在框架中的各个部件高度独立,可拆可组(任意拆卸,任意组合),着力通用。
* 部件细化,设计精巧,运行高效,内存占用低。
* 耦合度低(可拆可组)
* 高效:不论是什么系统,我们都希望架构是高效的。
* 安全:运行安全稳定【可以通过完善TDD测试机制来保障】
* 延展:我们需要架构具有可拓展性,以适应未来可能的变化。
* 简明:一个复杂的架构不论是测试还是维护都是困难的。我们希望架构能够在满足目的的情况下尽可能的简单明了。【但是简单明了的含义究竟是什么好像并没有一 个明确的定义。例如:使用模式能够使设计变得简单,但这是建立在我熟悉设计模式的基础上。对于一个并不懂设计模式的人,他会认为这个架构很复杂。】
* 透明:把过多的实现细节隐藏起来,仅把需求的接口呈现出来(具体的实现对使用Framework的开发者来说就是透明的)。这样就提高了使用者的效率,降低了学习的门槛。

设计具体指导原则:
1、概要框架总体功能目的
2、对框架总体功能目的进行细化,分层(层次之间相对独立,互不干涉),仔细斟酌,理清层次之间的依赖关系(如,核心层,中间层,应用层)。
* 核心层:处于最低层,不依赖于Framework中的其它层;
* 中间层:根据具体 Framework 的需要自行定义,取名,注意理清层次之间的依赖关系;
* 应用层:在核心层以上,依赖于核心层;
3、从核心层开始,逐层细化各个部件,仔细推敲部件名称,构思部件的功能,合理归类。

ok,现在让我们看看 ORM Framework 的是为了解决什么问题而出现的呢?
面 向对象建模和编程经过这么多年的发展已经相当成熟,其优势在于能够适应软件开发过程中的不断变化的需求。在面向对象编程的时候很显然我们建立的对象是放在 计算机内存之中,如果关闭计算机那么我们的对象就不存在了,对象的永久性(也就是长久保存对象)是我们一直的期望。在O/R Mapping出现前我们设计程序不得不花费大量的精力和时间构建我们的Data Access Layer (DAL数据存取层),如果项目规模比较大的时候可想而知这个DAL层的复杂程度,涉及到异构数据库那就更加复杂。

在我看来,ORM Framework 的出现是为了解决两个问题:
1. 数据库无关性:平滑迁移数据库和异构数据库;
2. 实体对象的持久性:关系数据库的数据与对象的对应关系。

从这里就可以初步看出,架构至少有两个层次:
1. 数据库存取层Database Access Layer作为核心层,实现数据库无关性;
2. 实体对象映射层 ObjectMapping Layer 作为应用层实现数据到实体对象的映射,该层依赖于核心层。

数据库存取核心层是独立通用处于最底层的实现,可以直接拿出来使用的,必须保持高效和安全,主要的功能如下:
* 规范数据库操作,构造 Database 工厂模式(可拓展性),形成数据库操作包裹类 【微软的 Data Access Application Block 】
* 规范 SQL 语句,解决不同的数据库之间的 SQL 语句的差异【最简单的方式方式就是在程序中以SQL语句Id的形式调用SQL语句,将SQL语句集中于一个文件。iBatis 的 DataMapper 采用类似机制,不过它采用的是XML格式,格式的冗余数据降低了加载的效率,在保存加载机制上不够灵活,至少该让用户选择保存为不同的格式;iBatis DataMapper 另一个问题就是将 ObjectMapping 也包含其中,层次不分明,降低可复用性,】。

实体对象映射层考虑的问题就多了:
* 简单实体对象属性的映射
* Collection对象属性的映射,如实体对象购物车的物品清单就是一个Collection对象属性,收录了该购物车中的所有的物品。
* 实体对象 MetaData 的考虑,
* 业务规则,约束的考虑等等。。。

这里我就映射这个问题随便说两句,实体对象映射层是效率最低的一个层次,原因在于映射操作:将实体对象变为数据库数据,数据库数据变为实体对象,而正是这个映射操作使得运行速度大大降低,内存占用大大的增加。
如 果将所有的实体数据不分青红皂白全部对象化,那么即使是采用Cache(是以牺牲内存为代价的)和分页机制(一次不要取个万把千条数据的,客户也看不过 来,一次百来条数据就差不多了,这样就减少了内存的占用和映射操作的时间),但是,当系统面临逐渐增加的并发访问数量面前,系统的性能恶化相当厉害。我不 知道大家说的什么才算是大型系统,企业级应用,也许是特指那些愿意花高价购买IBM RS/6000之流的机器的冤大头们吧。但是对于我们这些搞技术的,则是该将注意力集中在如何充分挖掘机器的每一分潜力上才是,我相信对于每一个量入为出 的企业来说,它应该是欣赏的。
这个目前,我也没有想到什么好的办法,对于减少内存开销,有个建议就是在设计时候,尽可能的延迟加载时间(如实体对 象购物车的物品清单,实际数据的加载只有当访问该属性的时候才加载,而对于大的备注,Blob类型的属性也可以采取类似的机制)。实际上,大多数用户的操 作都是在浏览,因此对于浏览数据的形式,可以绕过ObjectMapping层,通过数据库存取层返回dataset直接操作,这样也能进一步提高速度和 降低内存的消耗。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏