在这里,我们所要讨论的架构设计是企业应用软件的架构设计,而不是其它的软件系统架构的设计,例如:电信软件设计,和一般的企业应用软件的架构设计还是非常不一样的,电信软件会更多和硬件相结合。我在这个博客上发布的关于企业应用软件的架构设计的知识,都来自于我读的有关与软件架构设计的书籍,在我自己将书籍的内容消化之后,我希望我可以用浅显易懂的文字将我学到的知识描述出来。
好了,言归正传。
应用软件的架构一般分三层,表现层、领域层、数据源层。表现层负责提供服务,显示信息,主要和终端用户打交道;领域层包含业务逻辑,是系统真正的核心;数据源层负责与数据库、消息系统、事务管理器以及其它软件包通信。有时还会在领域层中抽象出来一层服务层,主要负责和表现层进行交互。
举例来说,当我们打开天猫商城 www.tmall.com这个网站,在天猫上看到的所有商品页面以及购买等所有操作显示的页面,就可以代表表现层;那么,我们在天猫商城上付钱购买商品,然后商家发货、我们收货确认这一系列流程是如何实现的呢?实现购买整个流程的逻辑的代码就是领域层;最后,在天猫上,我们购买过的所有商品 ,生成的订单,都是有记录的,可以查询的,这些信息是存储在哪里的呢?它们都是存储在数据库当中的。那这些数据又是怎么存储进入数据库的呢?好了,负责把这些信息存储进入数据库以及从数据库中提取出来的代码就形成了数据源层。
了解了软件架构的三个分层之后,我们来看看这三个层次具体应该如何设计。
先从领域层开始,因为这是系统的核心。领域层可选的设计模式有:事务脚本模式、领域模型模式以及表模块模式。这三种模式到底是怎么设计的,有什么不同,将放到后面的系列文章来讲,这里只对这三种模式做一个简单的解释:
1. 事务脚本模式,使用过程来组织业务逻辑。用过C语言的程序员应该就对面向过程来编程非常的熟悉。
2. 领域模型模式,这是面向对象的设计方式。 在应用程序中使用领域模型需要建立一个完整的由对象组成的层。数据和处理一般整合在一起。简单领域模型看起来与数据库设计很类似,这种设计中几乎每一个数据库表都与一个领域对象对应。而复杂的领域模型则与数据库设计不同,它使用继承、策略和其他设计模式,是一张由互联的细粒度对象组成的复杂网络。
服务层是从领域层中分离出来的一层,放置事务控制和安全等功能好场所。最小化情况下,服务层只是一个外观,所有实际的行为都在下层的对象中,服务层所做的只是将上层调用传递到更低层。在这种情况下,服务层提供一个更易于使用的API。另一个极端是将大多数业务逻辑都以事务脚本的形式置于服务层中,下层的领域对象变得极为简单。以上二者的折衷是: 控制器-实体风格,将单个事务或者用例所持有的逻辑置于事务脚本之中,他们通常被称为控制器或服务。
3. 表模块模式,以一个类对应数据库中的一个表来组织领域逻辑,而且使用单一的类实例来包含将对数据进行的各种操作程序。
再看数据源层,这里只说概念,每个概念的具体代码实现请见后续文章。
1. 事务脚本的数据源:行数据入口和表数据入口
行数据入口:为查询语句返回每一行产生一个它的实例。
表数据入口: 数据库中的每个表,仅仅需要一个对象来管理。这种表数据入口提供了查询数据库的方法,返回一个记录集。
2. 表模块的数据源:表数据入口。
3. 领域模型的数据源:缺点是与数据库的链接很复杂。
如果领域模型很简单,数据源使用活动记录就可以了,耦合更松的一些方式是使用表数据入口或行数据入口。当复杂度进一步增加,可以考虑使用数据映射器(O/R映射),特别推荐工作单元。
活动记录:让每个领域对象负责数据库的存取过程,这就是活动记录。从另一个角度来考虑活动记录,就是从行数据入口开始,然后把领域逻辑加入到类中。
O/R映射:面向对象的对象模型和关系型数据库的数据结构之间的相互转换。
工作单元:跟踪所有从数据库中读取的对象以及所有以任何形式修改过的对象。它同样负责将更新提交到数据库。
最后看表现层(Web层)。
构建Web层的方法主要有两种,一种是使用脚本,另一种是使用服务器页面。脚本形式的例子是CGI脚本和Java servlet , ASP, JSP和PHP等就是服务器页面。当前业界都采用MVC设计模式,来保证web表现层和领域层的完全分离。M代表领域层及数据源层,V代表表现层的视图层,C是控制器,是处理视图层与用户交互的部分,还可处理应用程序流,决定视图应该按什么次序出现。
在视图方面,可以考虑三种模式:转换视图、模版视图、两步视图。
模版视图:代表ASP、JSP、PHP,允许你在网页的结构中编写表现层,并在网页中嵌入标签,用以指明网页中的动态内容需要导向哪里。
转换视图:XSLT,可将xml转换为其它格式的文件,例如视图文件。
两步视图:由领域数据产生一个逻辑视图,然后将它发送到HTML网页中,形成第二阶段的页面,对于同一领域数据,第一阶段产生的逻辑视图是一样的,第二个阶段的页面可以是不一样的。如果Web应用程序提供的服务是由多种前端用户来使用,那么就应该使用两步视图。
应用软件架构中每一层的设计思路已经说完了,那么,在软件系统架构设计中,还有哪些问题需要考虑呢?
1. 离线并发问题
在Web项目中,离线并发显得尤其严重。例如,用户A和用户B同时修改数据库中的某张表的R行,加入R行有两个字段分别是C1,C2。
假如按照如下过程修改:
1 用户A将数据R(C1,C2)读取到A的浏览器中。
2 用户B将数据R(C1,C2)读取到B的浏览器中。
3 用户A在浏览器上将数据修改为R(C1’,C2),同时更新到数据库。
4 用户B在浏览器上将数据修改为R(C1,C2’),同时更新到数据库。
上述过程存在两个问题,第一,第4步B在修改数据的时候数据库中的数据和B的浏览器中数据已经不一致了;第二,如果程序按照哪个字段变化就在数据库中更新哪个字段的方式处理的话,那么经过上述四步修改,数据库中R行的内容是(C1’,C2’),这和A或者B的想法都不同(A认为是(C1’,C2),B认为是(C1,C2’))。
上述过程中A对数据库的修改过程或者B对数据库的修改过程,都是无法根据数据库的最新内容做修改,所以称为离线。以上的情况叫离线并发。
解决离线并发问题的机制是使用锁,如何使用后续文章讲具体讲解。
2. 会话状态
在企业应用软件系统中,有时需要记录同一个用户发出的不同请求之间的状态和数据,这就需要存储用户的会话状态。
存储会话状态的方法有如下三种:
客户端会话状态:在客户端保存数据:例如使用cookie 。
服务器会话状态:将各次请求之间的数据放在内存里,也可将对象存放在应用服务器的文件系统中,或者共享数据源中。
数据会话状态:将会话数据分解成多个表和域,保存在数据库中。
3. 分布策略
什么叫是分布策略?用简单通俗的话来讲就是将企业应用软件放到多个服务器上运行以提高系统的性能,那么如何将企业应用软件分布到多个服务器上,就叫做分布策略。
什么时候比较适合使用分布策略?
(1)客户机和服务器之间
(2)应用服务器和数据库之间
(3)Web服务器与应用服务器之间
(4)还有可能由于厂商不同而进行进程划分
使用分布策略的基本原则是什么?
(1)不能按照类模型进行分布,因为两个独立进程间的过程调用慢了一个数量级,不要分步使用对象。
(2)本地接口最好是细粒度接口,远程接口最好是粗粒度,一次可以获取多个信息的接口。
(3)使用集群系统,在每一个处理器上都部署所有的对象并在其它几个节点上复制它们,这样一来,每个处理器上的对象只需要用到本地调用,从而运行更快。
好了,企业应用软件架构设计的概述大致就讲完了。