
🎬 那我掉的头发算什么 :个人主页
🔥 个人专栏 : 《javaSE》《数据结构》《数据库》《javaEE》
⛺️待到苦尽甘来日

引言
在完成 Spring MVC 基础功能的开发练习后,我们发现了一个亟待解决的问题:即便只是实现了少量核心功能,项目代码已呈现出混乱的状态;若后续完成全量业务功能的开发,代码体系(包括文件结构与代码内容)将会陷入更严重的无序状态。因此,接下来我们学习应用分层。
文章目录
MVC与三层架构
阿里开发手册中, 关于工程结构部分, 定义了常见⼯程的应用分层结构:

那么什么是应用分层呢?
应用分层
应用分层是一种软件开发设计思想,它将应用程序分成 N 个层次,这 N 个层次分别负责各自的职责,多个层次之间协同提供完整的功能。根据项目的复杂度,可把项目分成三层、四层或者更多层。
常见的 MVC 设计模式,就是应用分层的一种具体体现。
为什么需要应用分层?
在最开始的时候,为了让项目快速上线,我们通常是不考虑分层的。但是随着业务越来越复杂,大量的代码混在一起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动一处就牵一发而动全身等问题。所以学习对项目进行分层就是我们程序员的必修课了。
如何分层(三层架构)
咱们上一节中学习的 "MVC",就是把整体的系统分成了 Model(模型)、View(视图)和 Controller(控制器)三个层次,也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是一种标准的软件分层架构。

目前更主流的开发方式是 "前后端分离" 的方式,后端开发工程师不再需要关注前端的实现,所以对于 Java 后端开发者,又有了一种新的分层架构:把整体架构分为表现层、业务逻辑层和数据层。这种分层方式也称之为 "三层架构"。
- 表现层:就是展示数据结果和接受用户指令的,是最靠近用户的一层;
- 业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现;
- 数据层:负责存储和管理与应用程序相关的数据。
可以看到,咱们前面的代码,并不符合这种设计思想,而是所有的代码堆砌在一起。

按照上面的层次划分,Spring MVC 站在后端开发人员的角度上,也进行了支持,把上面的代码划分为三个部分:
请求处理、响应数据:负责接收页面的请求,给页面响应数据。
逻辑处理:负责业务逻辑处理的代码。
数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。
这三个部分,在 Spring 的实现中,均有体现:

Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
Service:业务逻辑层。处理具体的业务逻辑。
Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查。
MVC 和三层架构的区别和联系
关于二者的关系,一直存在不同的观点。有人认为三层架构是 MVC 模式的一种实现,也有人认为 MVC 是三层架构的替代方案,等等各种说法都有。根本原因是大家站在不同的角度来看待这个问题的。
从概念上来讲,二者都是软件工程领域中的架构模式。
MVC 架构模式由三部分组成,分别是:模型(Model)、视图(View)和控制器(Controller)。
三层架构将业务应用划分为:表现层、业务逻辑层、数据访问层。
MVC 中,视图和控制器合起来对应三层架构中的表现层。模型对应三层架构中的业务逻辑层、数据层,以及实体类。

二者其实是从不同角度对软件工程进行了抽象。
MVC 模式强调数据和视图分离,将数据展示和数据处理分开,通过控制器对两者进行组合。
三层架构强调不同维度数据处理的高内聚和低耦合,将交互界面、业务处理和数据库操作的逻辑分开。
角度不同也就谈不上互相替代了,在日常的开发中可以经常看到两种共存的情况,比如我们设计模型层的时候往往也会拆分出业务逻辑层(Service 层)和数据访问层(Dao 层)。
但二者的目的是相同的,都是 "解耦,分层,代码复用"。(高内聚、低耦合)
代码重构
我们以图书管理系统为例,将我们之前的代码按照上面的思想改造。
先创建四个包:

重构后的代码:
Controller:
java
package com.hbu.book.controller;
import com.hbu.book.model.BookInfo;
import com.hbu.book.service.BookService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("book")
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList(){
BookService bookService = new BookService();
List<BookInfo> books = bookService.getBookList();
return books;
}
}
Service:
java
package com.hbu.book.service;
import com.hbu.book.dao.BookDao;
import com.hbu.book.model.BookInfo;
import lombok.val;
import java.util.List;
public class BookService {
public List<BookInfo> getBookList(){
BookDao bookDao = new BookDao();
List<BookInfo> books = bookDao.mockData();
for(BookInfo book : books){
if(book.getStatus() == 1){
book.setStatusCN("可借阅");
}else {
book.setStatusCN("不可借阅");
}
}
return books;
}
}
Dao:
java
package com.hbu.book.dao;
import com.hbu.book.model.BookInfo;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BookDao {
public List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 5; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("书籍" + i);
book.setAuthor("作者" + i);
book.setCount(i * 5 + 3);
book.setPrice(new BigDecimal(new Random().nextInt(100) + 1));
book.setPublish("出版社" + i);
book.setStatus(1);
books.add(book);
}
return books;
}
}
Model:
java
package com.hbu.book.model;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class BookInfo {
private Integer id;
private String bookName;
private String author;
private Integer count;
private BigDecimal price;
private String publish;
private Integer status; // 0-删除, 1-正常, 2-不允许借阅
private String statusCN;
}
尝试运行:


代码运行一切正常。

此时我们只需要看包名就能大致知道我们的代码在哪个地方,结构更有逻辑性。
应用分层的好处
应用分层作为主流的软件开发设计思想,其核心价值在于通过明确的职责划分优化项目结构,具体好处如下:
-
降低依赖,提升复用性:降低层与层之间的依赖关系,项目整体结构更加清晰明确,各层的核心逻辑可独立复用,避免重复开发。
-
聚焦职责,降低维护成本:开发人员可专注于整个结构中的某一层进行开发与维护,无需关注其他层的实现细节,极大缩短维护时间、降低维护难度与成本。
-
灵活替换,增强扩展性:可轻松用新的实现方案替换原有层次的实现,无需改动其他层的代码,适配业务迭代与技术升级需求。
-
规范开发,利于标准化:明确的分层规则为团队开发提供统一的设计规范,便于协作对接,推动开发流程与代码编写的标准化。
企业规范
详情请看:
https://developer.aliyun.com/article/1589859
以上就是本篇博客全部内容!