技术积累

明日复明日,明日何其多,我生待明日,万事成蹉跎。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

模式和架构读书笔记《企业应用架构模式》一

Posted on 2005-07-16 15:54  追风逐云.NET  阅读(433)  评论(0编辑  收藏  举报

引言

n         构建计算机系统并非易事。随着系统复杂性的增大,构建相应软件的难度将呈指数增大。我们只有在不断的学习中进步,从成功经验中学习,从失败教训中学习,才有望克服这些困难。

n         很多人都试图给“架构”下定义,而这些定义本身却很难统一。能够统一的内容有两点:一点是“最高层次的系统分解”;另一点是“系统中不易改变的决定”。

n         全书实际上就是关于如何将企业应用组织成不同的层次,以及这些层次之间如何协同工作。大多数重要的企业应用都是按照某种形式的层次分层设计的;当然,在某些情况下,别的设计方式也有它们自己的价值,本书中我们将不会讨论这些方式,而把注意力集中在层次方式上,因为它是应用最广的设计方式。

n         我的工作主要是关于企业应用的。企业应用一般都涉及到持久化数据……企业应用一般都涉及到大量数据……企业应用一般还涉及到很多人同时访问数据……企业应用还涉及到大量操作数据的用户界面屏幕……通常需要与散布在企业周围的其他企业应用集成。

n         关于业务逻辑:我认为“业务逻辑”这个词很滑稽,因为很难找出什么东西比“业务逻辑”更加没有逻辑。……现实业务中成千上万的“一次性特殊情况”最终导致了复杂的业务“无逻辑”,使得商业软件的开发那么困难。

n         关于性能的一些概念:
响应时间是系统完成一次外部请求处理所需的时间;
响应性不同于请求处理,它是系统响应请求的速度有多块(比如在执行后台任务时显示一个进度条就能够提高用户界面的响应性);
等待时间是获得系统任何形式响应的最小时间(主要体现在远程调用的网络延迟);
吞吐率是给定时间内能够处理多大的请求量;
性能或者指吞吐率,或者指响应时间,由用户自己决定;
负载是关于系统当前负荷的表述;
负载敏感度是指响应时间随负载变化的程度;
效率是性能除以资源;
系统的容量是指最大有效负载或吞吐率的指标;
可伸缩性度量的是向系统中增加资源(通常是硬件)对系统性能的影响(垂直可伸缩性一般指增加服务器,水平可伸缩性一般指提高单个服务器的性能)。

当构建企业应用系统时,关注硬件的可伸缩性往往比关注容量或效率更重要(购买新硬件往往比费劲地提高软件性能来得更便宜)。

 

全书分为两大部分:第一部分“表述”,从第一章到第八章,对全书涉及到的内容进行简要的介绍;第二部分“模式”,从第九章到第十八章,详细讲解各种具体的模式,包括运行机制、使用时机以及示例。

第一章 分层

在分解复杂的软件系统时,软件设计者用得最多的技术之一就是分层。在计算机本身的架构中,可以看到,到处都有分层的例子。

将系统按照层次分解有许多重要的好处:

n         在无需过多了解其他层次的基础上,仍然可以将某一层作为一个有机整体来理解和使用。

n         可以在保持接口不变的前提下替换某层的实现,而不影响使用它的其他层。

n         可以将层次间的依赖降到最低。

n         分层有利于标准化工作。

n         一旦构建好了某一层次,就可以用它为很多服务提供服务。

但分层也有自己的缺陷:层次并不能封装所有的东西;过多的层次会影响性能等。

本书主要对三个基本层次的架构展开讨论:表现层、领域层(业务层)和数据源层。分层架构中最困难的问题是决定建立哪些层次以及每一层的职责是什么。一种不太正规的测试办法是:假想向系统中增加一个完全不同的新层,例如为WEB应用增加一个命令行界面层;如果在这个过程中,发现需要重复实现某些功能,则说明可能有一些应该在领域层实现的逻辑,现在在表现层实现了。类似的,你也可以假想一下,将后台数据库更换成XML文件格式,看看情况又会如何?

BTW,在讨论具体的层次之前,个人觉得,要构建架构良好、健壮的系统,分层的思想是必不可少的,但现实中由于种种原因(包括客观原因和主观原因:比如项目规模、开发人员能力等等),往往并不能够做到纯粹的分层架构,这就得根据实际情况稍微变通,以取得整体上最优的方案。

这一章中,作者给出了一个怎样确定分层边界的方法,该方法虽然简单,却很有效。

第二章 组织领域逻辑

由于领域层介于表现层和数据源层的中间,因此确定其边界是最困难的,也面临更多的挑战,我想,这也是作者把这一层单独作为一章来介绍的原因。

领域逻辑的组织可以分为三种主要的模式:事务脚本、领域模型以及表模块

事务脚本通俗的说,就是面向过程的模式,将各种业务通过一个个的子程序来实现,这些子程序既负责获取用户输入,也负责将操作结果保存到数据库中;领域模型通俗的说,就是面向对象的模式,通过各种业务对象的相互作用来完成业务,每个对象都明确承担一部分工作;表模块和领域模型很相似,不同的是领域模型中的对象对应的是数据库中的一条记录,而表模块中的对象对应的是数据库中的整张表。

三种模式各有优缺点。事务脚本比较容易理解,但系统越复杂它就越难以维护;领域模型非常规范,但要纯粹的实现它,需要面临的主要问题是对象和关系数据库之间的映射问题;表模块介于两者之间,很多开发平台对表模块和基于记录集的编程都有非常好的支持,因此,它往往是一个不错的折中选择。

第三章 映射到关系数据库

这一章要讨论的问题是领域层如何访问数据库的问题。作者给出了几种模式:行数据入口、表数据入口、活动记录、数据映射器。

行数据入口模式是指对数据库中的每一条记录建立一个对象与其相对应,该对象提供该数据的属性和操作接口;表数据入口是指对数据库中的每一个表建立一个对象(一般是记录集)与其相对应,该对象提供该表的操作接口;通过在行数据入口模式的对象中添加业务逻辑,就形成了活动记录模式,该对象既负责数据库基本操作,又提供业务接口;当领域逻辑越来越复杂时,活动记录中的对象将难以直接和数据库表一一对应,这时,就可以将这些对象分为业务对象和数据映射器对象来解决这个问题,其中数据映射器对象仍保持和数据库的一一对应,而业务对象使用数据映射器对象提供的接口来实现数据操作,这就形成了数据映射器模式

根据不严格的观察,关系数据库的映射开销大概是程序开发总开销的1/3左右,而且还会一直持续到维护阶段。在发展过程中,出现了面向对象数据库,试图解决这些问题,然而由于其成熟程度以及出于规避风险的原因,大多数项目并不使用它。另一方面,O/R映射工具却为这个问题提供了一个较好的解决途径,获得O/R映射工具的途径可以是购买或者自己开发,我想很多开发人员都在做这个工作。

关于读取数据的一些讨论:作者把读取数据的方法看作一个查找器,那么在什么地方放置查找器呢?讨论后得出一个通用的参考方式是:查找器可以和表数据入口对象放在一起,如果是行数据入口,则应该单独创建查找器对象。

当人们谈到对象-关系映射的时候,他们多半说的是结构映射模式,在内存对象与数据库表的映射中会用到他们。作者对关系的映射、继承的映射、数据库连接池等问题进行了一些一般性的讨论,这里就不多讲了。