SaaS系列介绍之十三: SaaS系统体系架构
1 系统体系架构设计
软件开发中系统体系架构决定了一个系统稳定性、健壮性、可扩展性、兼容性和可用性,它是系统的灵魂。体系架构是架构师所关注的核心。良好的体系架构是系统成功的开端,否则,再好的代码与设计也无济于事。
2 当前.net主要的开发框架简介
l Castle
Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架、AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务。其中关键的技术是ActiveRecord,Facilities,MonoRail等等。
优点:体现了ORM、IOC、ActiveRecorder思想,MVC框架。
不足:框架层次划分不太清楚。
l PetShop
PetShop是微软用它来展示.Net企业系统开发的能力。PetShop4.0,这个实例是Microsoft针对SQL Server 2005 以及Visual Studio 2005发布的。其中运用了一些新的技术。缓存数据与数据库的更新同步,新的Web控件,以及母版的应用,异步通讯,消息队列。这些都是很实用的技术。PetShop中大量运用了抽象工厂模式,由于采用了Master Pages,Membership,以及Profile,表现层的编码量减少了25%,数据层的编码量减少了36%。
图1 PetShop4.0的体系架构
PetShop4.0在数据访问层(DAL)中,采用DAL Interface抽象出数据访问逻辑,并以DAL Factory作为数据访问层对象的工厂模块。对于DAL Interface而言,分别有支持MS-SQL的SQL Server DAL和支持Oracle的Oracle DAL具体实现。而Model模块则包含了数据实体对象。可以看到,在数据访问层中,完全采用了“面向接口编程”思想。抽象出来的IDAL模块,脱离了与具体数据库的依赖,从而使得整个数据访问层利于数据库迁移。DALFactory模块专门管理DAL对象的创建,便于业务逻辑层访问。SQLServerDAL和OracleDAL模块均实现IDAL模块的接口,其中包含的逻辑就是对数据库的Select,Insert,Update和Delete操作。因为数据库类型的不同,对数据库的操作也有所不同,代码也会因此有所区别。
此外,抽象出来的IDAL模块,除了解除了向下的依赖之外,对于其上的业务逻辑层,同样仅存在弱依赖关系。
优点:体现了工厂模式ORM,IOC思想,.Net企业级开发。
不足:没有ORM思想。
l Nhibernate
Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于ADO.Net)进行了非常轻量级的对象封装,使得程序员可以随心所欲的使用对象编程思维来操纵数据库,目前在国内Java开发界已经颇为流行。而NHibernate,如同NUnit,NAnt一样,是基于.Net的Hibernate实现。主要体现了ORM的思想,解决了分层开发中的持久层的问题,在N层开发中非常重要。
优点:体现了ORM,持久层。
不足:配置复杂,过份信赖于XML文件。
所用技术总结:
OR Mapping思想,分层架构思想,Castle-ActiveRecorder,Atlas,反射,设计模式(单例模式,简单工厂模式,策略模式),XML,IOC,框架。
3 当前J2ee主要的开发框架简介
l Struts 框架
Struts框架是一开源产品,基于模型-视图-控制器(MVC)设计范例来开发Web应用软件。它使用并且扩展了Java Servlet API,最初由Craig McClanahan创建。在2000年5月,它被捐赠到Apache Foundation。Struts框架展示了一个强有力的定制标签库,平铺显示,表单检验和I18N(国际化)。另外,Struts支持许多描述层,包括JSP,XML/XSLT使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库,JavaServerFaces(JSF)和Velocity;还支持一些模型层,包括JavaBeans和EJB。
下面是Struts的核心内容:
JSP(TagLib)――>ActionForm――>Action ――> Event――>EJBAction――>EJB――>DAO――>Database
JSP(TagLib) (forward) <――Action<――EventResponse<――
优点:基于MVC模式,结构很好,基于JSP。
不足:扩展性不太好,逻辑复杂的大型项目不适用,框架层次划分不太清楚。
l Spring框架
Spring框架是一个分层的Java/J2EE应用程序框架,基于Expert One-on-One J2EE设计和发行的代码。Spring框架提供一种简单的开发技术,用于自动化处理工程中大量的属性文件和助理类。
Spring是一个开源框架,由Rod Johnson创建并且在他的著作《J2EE设计开发编程指南》里进行了描述。它是为了解决企业应用开发的复杂性而创建的。Spring使使用基本的JavaBeans来完成以前只可能由EJB完成的事情变得可能了。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
Spring框架包括的主要特色有:
1 强有力的基于JavaBeans的配置管理,使用Inversion-of-Control(IoC)原则。
2 一个核心bean工厂,可用在任何环境,从applets到J2EE容器程序。
3 通用的抽象层适合于数据库事务管理,允许可插入的事务管理器,并且不需要处理低层次的问题就可容易地划分各事务的界限。
4 一个很有意义的异常处理的JDBC抽象层。
5 与Hibernate集成到一起,DAO实现支持以及事务策略。
优点:体现了J2EE、容器、轻量级、控制反转、面向切面的思想。
不足:结构复杂,不易理解。
l Hibernate框架
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,它提供一个易用的框架来实现把一个面向对象的域模型映射到一传统的关系数据库,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。它不仅负责从Java类到数据库表格(以及来自Java数据类型的SQL数据类型)的映射,而且还提供数据查询和检索能力,并能大大减少花在SQL和JDBC手工数据处理上的开发时间。最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
Hibernate的目标是减轻开发者的与大量普通的数据持续性相联系的编程任务。Hibernate还能够适应开发进程,无论它是刚开始设计还是来自一现成的数据库。Hibernate可以自动生成SQL,使开发者摆脱了手工处理结果集和进行对象转化的繁琐任务,并能使应用程序移植到所有的SQL数据库。它还能提供透明的持续性,对持续性类的唯一的要求的是实现一个无参数的构造器。
优点:主要应用在EJB层,可配置性强,灵活,简化了数据库操作。
不足:难以配置。
4 常见的软件体系架构
l 三层体系架构
在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或成为领域层)、表示层,如图所示:
图2 三层体系架构
数据访问层:有时候也称为是持久层,其功能主要是负责数据库的访问。简单的说法就是实现对数据表的Select,Insert,Update,Delete的操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。
业务逻辑层(BusinessRules):是整个系统的核心,它与这个系统的业务(领域)有关。以STS系统为例,业务逻辑层的相关设计,均和销售跟踪的逻辑相关。在结构上它封装了数据访问层的相关操作。该层主要由实现具体业务逻辑的类组成。
表示层(WebUI):是系统的UI部分,负责使用者与整个系统的交互。在这一层中,理想的状态是不应包括系统的业务逻辑。表示层中的逻辑代码,仅与界面元素有关。在当前项目中,是利用ASP.NET来设计的,因此包含了许多Web控件和相关逻辑。
l 五层体系架构
SaaS软件体系架构也可以分为五层,从上而下分别为:用户界面层(表现层)、业务逻辑层、通用层、应用框架层、远程访问(WebService)层、数据访问层,如图所示:
图3 基于微软的.NET架构设计
用户界面层(UI)
用户界面层是用户直接操作的界面。该层由界面外观、表单控件、框架及其它部分构成。用户界面层负责使用者与整个系统的交互。在这一层中,理想的状态是不应包括系统的业务逻辑。表示层中的逻辑代码,仅与界面元素有关。在当前项目中,是利用ASP.NET来设计的,因此包含了许多Web控件和相关逻辑。
² 界面外观包括skip(皮肤)、Images(图片)、css(样式表)
² 表单控件主要包括常用表单、用户自定义控件。
² 框架主要包括Master Page、Frame Page。
² 其它主要包括JavaScript文件、Dll文件、Report报表、Schema建数据库、Model开发模板。
业务逻辑层(BusinessRules)
是整个系统的核心,它与这个系统的业务(领域)有关。以STS系统为例,业务逻辑层的相关设计,均和销售跟踪的逻辑相关。在结构上它封装了数据访问层的相关操作。该层主要由实现具体业务逻辑的类组成。
² BLFactory 业务逻辑工厂
² IBL 业务逻辑接口
² BusinessRules 业务逻辑实现
通用层
通用层贯穿整个项目的表示层和业务逻辑层。主要存放该项目中较为通用的常量定义和通用服务(Service),这里指的Service是当前项目业务逻辑上通用的方法,我们把它们写在对应的静态类中。以服务的形式提供。
CommonLayer:存放通用的常量及方法。
数据访问层
该层结构是最复杂的,主要由以下层组成:数据访问工厂层(DALFactory),数据访问接口层(IDAL),自定义查询层(PersistenceFacade),临时层(DataAccessLayer),数据持久层(PersistenceLayer)。
下面由下向上介绍:
² PersistenceLayer层,这是框架设计的最底层(除应用框架层外)。它主要负责用ORM思想将物理数据库对象化。简单来说就是将数据库表映射为实体类,将相应的字段映射为类的属性。这样一来物理数据库对于开发者是完全透明的,应用ORM的思想我们彻底摆脱了物理数据库。并且独立于数据库具体实现。
² 具体实现我们应用著名的开源项目Castle下的轻量级数据访问组件ActiveRecorder实现。
² PersistenceFacade层和IDAL,这里定义了项目中用到的所有查询方法。与PersistenceLayer层定义的数据实体相对应。在这些字定义的查询类中可以应用ActiverRecorder提供的三种查询方法(ActiverRecorderBase提供的简单接口,简单查询SimpleQuery,自定义查询CustomerQuery)的任意组合。并且这里的每一个类都要实现IDAL接口层定义的相关接口。
² DALFactory层,做为数据访问的工厂,通过.Net的反射机制调用IDAL和PersistenceFacade组成的数据访问组件中的相关操作。
² DataAccessLayer临时层。首先声明这层是完全没有必要的。因为我们在项目中是可以不写任何Sql语句的。所有的Sql都用Hql代替。设计这层的目的是为了允许项目组中的人员的技术过渡。此层可以通过Sql操作数据库(不推荐)。架构稳定后本层将不再提供。
应用框架层(Framework)
本层的目的是技术沉淀。将项目之间通用的东西移入应用框架层达到代码重用的目的。本层以后可以黑盒化。可以包括通用的组件。
² Framework:积累一些可以抽象出来的方法及控件
² MSMQMessag:消息处理队列的实现
² Pager:通用翻页类
² Report:通用报表类
² Controls:控件处理类
² DataFormat:数据格式转换类
² WebUI:页面处理类
² Validate:数据校验
² Object:对象之间的转换及访问
5 分层式体系结构的好处
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义。
一个好的分层式结构,可以使得开发人员的分工更加明确。一旦定义好各层次之间的接口,负责不同逻辑设计的开发人员就可以分散关注,齐头并进。例如UI人员只需考虑用户界面的体验与操作,领域的设计人员可以仅关注业务逻辑的设计,而数据库设计人员也不必为繁琐的用户交互而头疼了。每个开发人员的任务得到了确认,开发进度就可以迅速的提高。
松散耦合的好处是显而易见的。如果一个系统没有分层,那么各自的逻辑都紧紧纠缠在一起,彼此间相互依赖,谁都是不可替换的。一旦发生改变,则牵一发而动全身,对项目的影响极为严重。降低层与层间的依赖性,既可以良好地保证未来的可扩展,在复用性上也是优势明显。每个功能模块一旦定义好统一的接口,就可以被各个模块所调用,而不用为相同的功能进行重复地开发。
进行好的分层式结构设计,标准也是必不可少的。只有在一定程度的标准化基础上,这个系统才是可扩展的,可替换的。而层与层之间的通信也必然保证了接口的标准化。
“金无足赤,人无完人”,分层式结构也不可避免具有一些缺陷:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
6 软件架构视图
Philippe Kruchten在其著作《Rational统一过程引论》中写道:
一个架构视图是对于从某一视角或某一点上看到的系统所做的简化描述,描述中涵盖了系统的某一特定方面,而省略了于此方面无关的实体。
也就是说,架构要涵盖的内容和决策太多了,超过了人脑“一蹴而就”的能力范围,因此采用“分而治之”的办法从不同视角分别设计;同时,也为软件架构的理解、交流和归档提供了方便。
图4 Philippe Kruchten提出的4+1视图方法
该方法的不同架构视图承载不同的架构设计决策,支持不同的目标和用途:
l 逻辑视图:当采用面向对象的设计方法时,逻辑视图即对象模型。
l 开发视图:描述软件在开发环境下的静态组织。
l 处理视图:描述系统的并发和同步方面的设计。
l 物理视图:描述软件如何映射到硬件,反映系统在分布方面的设计。
图5 运用4+1视图方法针对不同需求进行架构设计
逻辑视图。逻辑视图关注功能,不仅包括用户可见的功能,还包括为实现用户功能而必须提供的“辅助功能模块”;它们可能是逻辑层、功能模块等。
开发视图。开发视图关注程序包,不仅包括要编写的源程序,还包括可以直接使用的第三方SDK和现成框架、类库,以及开发的系统将运行于其上的系统软件或中间件。开发视图和逻辑视图之间可能存在一定的映射关系:比如逻辑层一般会映射到多个程序包等。
处理视图。处理视图关注进程、线程、对象等运行时概念,以及相关的并发、同步、通信等问题。处理视图和开发视图的关系:开发视图一般偏重程序包在编译时期的静态依赖关系,而这些程序运行起来之后会表现为对象、线程、进程,处理视图比较关注的正是这些运行时单元的交互问题。
物理视图。物理视图关注“目标程序及其依赖的运行库和系统软件”最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性、可伸缩性等要求。物理视图和处理视图的关系:处理视图特别关注目标程序的动态执行情况,而物理视图重视目标程序的静态位置问题;物理视图是综合考虑软件系统和整个IT系统相互影响的架构视图。
7 小结
本文介绍了SaaS的体系架构设计方法。通过对.net主要的开发框架简介和J2ee主要的开发框架简介可以分析出各自的优势与不足。
同时介绍了软件体系架构的分层模式,通过具体分层体现了软件体系架构的核心价值,架构的模型可以在我们的开发中应用。