单体架构

单体分层架构

Web应用程序发展的早期,大部分工程是将所有的服务端功能模块打包到单个巨石型(Monolith)应用中,譬如很多企业的Java应用程序打包为war包,最终会形成如下的架构:

单体架构示意

巨石型应用易于搭建开发环境、易于测试、易于部署;其缺陷也非常明显,无法进行局部改动与部署,编译时间过长,回归测试周期过长,开发效率降低等。在Web2.0时代刚刚流行的时候,互联网应用与企业级应用并没有本质的区别,集中式架构分为标准的三层:数据访问层、服务层和Web层。

  • 数据访问层用于定义数据访问接口,实现对真实数据库的访问;
  • 服务层用于对应用业务逻辑进行处理;
  • Web层用于处理异常、逻辑跳转控制、页面渲染模板等。

单体架构与微服务对比

MVC三层架构

Web2.0时代刚刚流行的时候,互联网应用与企业级应用并没有本质的区别,集中式架构分为标准的三层:数据访问层、服务层和Web层。

  • 数据访问层用于定义数据访问接口,实现对真实数据库的访问;
  • 服务层用于对应用业务逻辑进行处理;
  • Web层用于处理异常、逻辑跳转控制、页面渲染模板等。

数据访问层

这三层之间既可以共享领域模型对象,又可以进行更加细致的拆分。通常的做法是,数据访问层使用实体对象(Entity),每个实体对象对应数据库中的一条数据。实体对象和值对象(VO)组成领域模型(Domain Model,被服务层使用。而逻辑控制层由于需要和前端的Web页面打交道,需要封装大量的表单,因此使用由领域模型转换的数据传输对象(DTO。服务层是整个系统的核心,它既直接提供公开的API,也可以通过Web层提供API。服务层同时可以提供部分私有实现,用于屏蔽底层实现细节。数据访问层应该只由服务层直接调用,它无须公开任何公有API

由于NoSQL在传统三层架构模型时代还未兴起,因此数据访问层主要是对关系型数据库进行访问。在Java开发中,访问关系型数据库要通过统一的接口,即JDBC。通过JDBC可以无缝地切换至不同的数据库。常见的关系型数据库有Oracle、SQLServer、MySQLDB2等,这些经典的关系型数据库也一直沿用至今。

然而存储于关系型数据库的二维关系表格数据与面向对象的域模型并不容易一一映射,因此出现了很多ORM(Object-Relationship-Mapping)框架。MyBatis及其前身IBATISJPA以及它的默认实现Hibernate,这些都是ORM领域中开源框架的翘楚。JPAJava官方的持久化层规范,其完全以面向对象理念去操作数据库,这种方式虽然设计新颖,但实际用起来却略显笨重。因此,很多互联网公司都采用了更加轻量、可控性更高的MyBatis作为ORM框架的首选。

服务层

服务层用于编写应用的具体业务逻辑,它需要一个使用便捷且可以对数据访问层和Web层承前启后的框架。Java官方推荐的EJB 2.X过于笨重,其中大量的XML配置以及烦琐的部署方式,使得它使用起来非常不便。虽然后来Sun公司又推出了EJB 3.X,在使用上简化了很多,但依然无法成为Java开发的标准。

RodJohnson这位业界大神开发的Spring Framework,极大地简化了JavaEE的开发,它提供的IOC(控制反转)和AOP(面向切面编程)特性为开发者提供了便利,并且迅速地成了Java后端开发的实际标准。Spring Framework提供了一个容器,容器中的任何对象都以Bean的方式注入,它像胶水一样优雅地粘贴数据访问对象和其他第三方组件,它并不仅仅是一个定位于服务层的框架,而是一个贯穿于应用整个生命周期的生态圈。

Web

Web层用于分离前端展现和后端服务。由于Java的标准实现——Servlet侵入了大量的HttpRequest、HttpResponse、HttpSessionAPI,导致基于Servlet开发的程序并不适合用于单元测试,而且实现配置、跳转、表单封装等操作时也需要做大量的重复工作,因此,很多MVC框架应运而生,用于改善开发流程。

常见的MVC框架有Strtus1.X,以及基于WebWork封装的Struts 2.XSpringMVC。初期Struts系列由于使用简单而备受青睐,后来SpringMVC投入的力度越来越大,由于其更加清晰的设计理念以及强大的与Spring Framework融合的能力,使得它渐渐成为业界主流。在这种AllinOne的集中式架构下,每个开发者都是全栈工程师。由Spring + Struts(Spring MVC)+Hibernate组成的SSH框架套件,或由Spring + Struts(SpringMVC)+ IBATIS(MyBatis)组成的SSI框架套件,成了技术选型的主流。当时的软件工程方法论主要关注质量保证和设计灵活性,TDD(测试驱动开发)和DDD(领域驱动开发)也是时常被讨论的话题。

上一页
下一页