Songtao Hu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

持久化(persistence)是应用程序开发中的一个基本关切。如果你有一些软件开发的经验,你已经处理过它了。几乎所有的应用程序需要将数据持久化。你使用持久化来允许数据被存储,甚至当使用这些数据的程序不在运行状态时也可以。

为了演示,我们假设你需要创建一个应用程序,让用户存储他们公司的电话号码和联络详情,然后在需要的时候获取它们。除非你想让用户永远都运行这个程序,否则你将很快意识到你的应用程序需要将联络信息以某种方式保存在某个地方。你遇到了持久化的决策:你需要制定好使用哪一种持久化机制。你有将数据存储在许多地方的选项,最简单的将是文本文件。然而通常你会选择关系型数据库,因为这样的数据库能够被广泛理解,并且为可靠地存储和获取数据提供了丰富的特性。

1.1.1  关系型数据库

你很可能已经接触过关系型数据库,诸如Microsoft SQL ServerMySQLOracle。如果还没有,见附录A。大多数开发者每天都使用关系型数据库;关系型数据库被普遍认同并且作为应对现代数据管理挑战的一个牢固而成熟的解决方案。

关系型数据库管理系统(RDBMS)并不是.NET特有的,对于任何一个应用,关系型数据库也并不需要是特定的。你可以有一些应用程序访问一个单一的数据库,一些是用.NET编写的,另一些是用JavaRuby等编写的。关系技术提供了在许多不同的应用之间共享数据的一种方式。甚至一个单独的应用程序内部的不同组件可以独立地访问一个关系型数据库(例如:一个报表引擎和一个日志组件)。

关系技术是许多不相关的系统和技术平台的共同特征。关系数据模型常常是业务对象的通用的企业范围的呈现:业务需要存储和不同事物相关的信息,诸如客户(customers)、账户(accounts)和产品(products)(业务对象)等,关系型数据库常常是精选的中央位置,在那里它们被定义和存储。这使得关系型数据库成为IT领域的一个重要方面。

关系型数据库管理系统(RDBMS)具有基于SQL的应用程序编程接口(APIs)。因此今天的关系型数据库产品被称为SQL数据管理系统,或者,当我们谈论特定的系统时,就称为SQL数据库。

1.1.2  理解SQL

如同任何.NET数据库开发,当你使用NHibernate的时候对于关系型数据库和SQL有一个坚实的理解是一个先决条件。你将使用SQL来调整你的NHibernate应用程序的性能。NHibernate使得许多重复的编码任务自动化,但是如果你想要利用现代SQL数据库的全部能量,你的持久化技术的知识必须超越NHibernate。记住潜在的目标是牢固性、持久化数据的有效率的管理。

如果你觉得你需要改进你的SQL技能,那么去获取几本优秀的书籍的拷贝吧,它们是Dan Tow的《SQL Tuning》、《SQL Cookbook on advanced SQL techniques》。Joe Celko也写了一些关于高级SQL技术的出色的书籍。如果需要更多理论方面的背景信息,请考虑阅读《An Introduction to Datbase Systems》。

1.1.3  .NET应用程序中使用SQL

.NET为了让应用程序和SQL数据库一起工作提供了许多工具和选择。你可能依赖Visual Studio IDE,利用它的拖拽功能:在一系列的鼠标点击,你就能创建数据库连接,执行查询,在屏幕上显示可编辑的数据。我们认为这一途径对于简单的应用是很好的,但是这一途径对于巨大的,更加复杂的应用则不能很好地伸缩。

作为另一选择,你可以使用SqlCommand对象和手工编写和执行SQL来构造数据集(DataSets)。这样做很快就会变得乏味单调;你希望工作在抽象层次稍微高一些的层次,这样你就可以专注于解决业务问题,而不是担心数据访问问题。如果你对于学习更多关于数据访问途径的大范围的尝试和测试,考虑一下阅读Martin Fowler的《企业应用架构模式》,它深入地解释了很多技术。

在所有的选项中,我们采取的途径是编写类 - 或业务实体 它能够从数据库加载并保存到数据库。不同于数据集(DataSets),这些类不是被设计成为对关系型数据库的结构做镜像处理(就像行和列)。取而代之的是,他们关心的是解决手头上的业务问题。这些类聚在一起,通常代表了面向对象的领域模型。

1.1.4  面向对象应用程序中的持久化

在面向对象应用程序中,持久化允许一个对象的生存期比创建它的进程或应用程序更长。对象的状态可以保存到磁盘,在将来某个时间点,一个具有相同状态的对象被重新创建。

这一应用程序并不限于单一对象 相互关联的完整对象图可以被持久化并在以后重新创建。大多数对象不是持久化的,瞬态(transient)对象是那种受实例化该对象的进程的生存所约束的,具有有限的生存期的对象。一个简单的例子是一个web控件对象,当它被渲染到屏幕并且被从内存中清除之前只在内存中生存了极短的一瞬间。几乎所有的.NET应用程序包含了持久化和瞬态对象的混合,有一个子系统来管理持久化是很明智的。

现代关系型数据库提供了持久数据的结构化的呈现,可以对数据排序、搜索和分组。数据库管理系统负责管理像并发和数据集成之类的事物;它们负责在多个用户和多个应用之间共享数据。数据库管理系统同样提供数据级的安全性。当我们在本书中讨论持久化,我们考虑所有这些事情:

n  存储、组织和获取结构化数据

n  并发和数据集成

n  数据共享

特别地,我们是在一个使用领域模型的面向对象应用程序的上下文中考虑这些问题。一个拥有领域模型的应用程序并不直接和表格式呈现的业务实体(使用DataSets)在一起工作;应用程序有它自己的,业务实体的面向对象的模型。如果一个数据库有ITEMBID表,那么.NET应用程序就定义ItemBid类而不是使用DataTable

因此,取代直接工作于DataTable的行和列,业务逻辑与面向对象的领域模型和它在运行时的实现,就也就相互关联的对象图,来相互交互。业务逻辑从来不会在数据库中执行(就像SQL存储过程);它在.NET中实现。这允许业务逻辑使用高级的面向对象概念,诸如继承和多态。例如,你能使用众所周知的设计模式,诸如:策略(Strategy)、仲裁者(Mediator)和组合(Composite)[GOF 1995],所有这些都依赖于多态方法的调用。

现在有一个警告:并不是所有的.NET应用程序是按这种方式设计的,也不应该是。简单的应用程序没有相关的领域模型可能会更好。SQLADO.NET可供用于处理纯的表格式数据,数据集(DataSet)使得CRUD操作更加容易。操作持久化数据的表格式呈现是直接的并且可以被很好理解。

但是在那些应用程序具有复杂业务逻辑的场合,领域模型帮助明显地改善代码复用和可管理性。我们在本书中专注于带领域模型的应用程序,因为NHibernateORM一般来说是和这类应用最具有相关性的。

理解领域模型是怎样适合更大图景的软件系统是很有帮助的。为了解释这一点,我们回过头来,看一看分层架构(layered architecture)

1.1.5  持久化和分层架构

许多系统,如果不是全部的话,是用分层架构设计的,NHibernate和这类设计配合得很好。什么是分层架构呢?

分层架构将系统分隔成一些分组,每一个分组包含了定位一个特定问题区域的代码。这些分组成为层(layers)。例如,用户界面层(也称为表现层)可能包含所有的用于构建web页和处理用户输入的应用程序代码。分层的一个主要好处是你能经常修改其中的一层而不会明显破坏其他层。因而使得系统减少脆弱性,同时更加可维护。

分层的实践遵循一些基本原则:

n  层的通信从上到下。层仅依赖于直接位于它正下方的层。

n  每一层除了它的正下方的层外,对其他任何层都不了解。

商业应用程序使用一个流行的、被证明的,高层次应用体系架构,包含三个层次:表现层,业务层,持久层。见图1.1

让我们仔细研究一下图中的层和元素:

n  表现层 用户界面逻辑是最上面的。在web应用程序中,这一层包含了负责绘制页面和屏幕的代码,搜索用户输入,控制导航。

n  业务层 这一层的确切形式在应用程序之间有很大不同。但是我们通常赞同业务层是负责实现那些用户将会作为问题领域的一部分来理解的业务规则或系统需求。在某些系统,这一层有它自己的业务领域实体的内部呈现。另一些系统,它复用由持久层定义的模型。我们将在第3章再次探讨这一问题。

n  持久层 持久层是这样一组类和组件,它们负责将应用程序的数据保存到一个或更多的数据存储,并且负责从那里取出数据。这一层在业务领域实体和数据库之间定义一个映射。听到NHibernate将主要被用于这一层,这不可能让你感到惊讶。

n  数据库 数据库存在于.NET应用程序之外。它是实际的、系统状态的持久的呈现。如果使用SQL数据库,数据库包含关系型架构,可能有存储过程。

n  帮助/实用工具类 每一个应用程序都有一套基础性的帮助或实用工具类来支持其他层:例如,界面小部件(UI widgets),消息(messaging)类,异常(Exception)类,日志实用工具。这些基础结构元素并不会考虑分层,因为它们并不遵守分层体系架构中的层间依赖性原则。

所有应用程序都应该有三层吗?

尽管三层架构在许多案例中是普遍的、有益的,但是不是所有的.NET应用程序都设计成那样,也不应该是。简单的应用程序没有复杂对象可能会更好。SQLADO.NET可供用于处理纯的表格式数据,ADO.NET数据集使得基本的操作更加容易。工作于持久化数据的表格式呈现是直截了当的,并且可以被很好理解。

记住,分层在切分巨大而复杂的应用时特别有用,对于极其简单的程序则常常是杀鸡用牛刀。对于如此简单的程序,你可以选择将所有代码放在一个地方。不是将业务规则和数据访问功能工整地放到单独的层中,取而代之的是,将它们全部放到你的web/Windows后端代码文件中。像Visual Studio.NET这样的工具使得构建这类应用程序是容易的和无痛苦的。但是要注意这种方式将很快导致出现有问题的代码;随着程序的扩展,你将不得不添加更多的代码到每一个窗体或页面,要处理的事物将变得越来越困难。而且,对于数据库的修改将很容易破坏你的应用程序,寻找和修复程序中这些受影响的部分将变得相当耗时和痛苦。

posted on 2012-04-20 21:57  Songtao Hu  阅读(986)  评论(0编辑  收藏  举报