单体架构
单体分层架构
在 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、MySQL 和 DB2 等,这些经典的关系型数据库也一直沿用至今。
然而存储于关系型数据库的二维关系表格数据与面向对象的域模型并不容易一一映射,因此出现了很多 ORM(Object-Relationship-Mapping)框架。MyBatis 及其前身 IBATIS,JPA 以及它的默认实现 Hibernate,这些都是 ORM 领域中开源框架的翘楚。JPA 是 Java 官方的持久化层规范,其完全以面向对象理念去操作数据库,这种方式虽然设计新颖,但实际用起来却略显笨重。因此,很多互联网公司都采用了更加轻量、可控性更高的 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、HttpSession 等 API,导致基于 Servlet 开发的程序并不适合用于单元测试,而且实现配置、跳转、表单封装等操作时也需要做大量的重复工作,因此,很多 MVC 框架应运而生,用于改善开发流程。
常见的 MVC 框架有 Strtus1.X,以及基于 WebWork 封装的 Struts 2.X 和 SpringMVC。初期 Struts 系列由于使用简单而备受青睐,后来 Spring 对 MVC 投入的力度越来越大,由于其更加清晰的设计理念以及强大的与 Spring Framework 融合的能力,使得它渐渐成为业界主流。在这种 AllinOne 的集中式架构下,每个开发者都是全栈工程师。由 Spring + Struts(Spring MVC)+Hibernate 组成的 SSH 框架套件,或由 Spring + Struts(SpringMVC)+ IBATIS(MyBatis)组成的 SSI 框架套件,成了技术选型的主流。当时的软件工程方法论主要关注质量保证和设计灵活性,TDD(测试驱动开发)和 DDD(领域驱动开发)也是时常被讨论的话题。