【Spring】从0到1掌握Spring MVC应用分层


🎬 那我掉的头发算什么个人主页
🔥 个人专栏 : 《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
以上就是本篇博客全部内容!

相关推荐
打工的小王2 小时前
Spring Boot(二)模版引擎
java·spring boot·后端
茶本无香2 小时前
设计模式之七—装饰模式(Decorator Pattern)
java·设计模式·装饰器模式
rannn_1112 小时前
【Javaweb学习|Day11】SpringBoot原理|配置优先级、Bean的管理、原理及源码分析
java·spring boot·后端·学习·javaweb
晚风吹长发2 小时前
初步了解Linux中的信号保存和简单使用
linux·运维·服务器·数据结构·后端·算法
马猴烧酒.2 小时前
智能协图云图库学习笔记day5
java·jvm·spring boot·笔记·学习·mvc
2501_933513042 小时前
Java后端开发者的AGI时代学习与职业路径策略
java·学习·agi
lixin5565562 小时前
基于迁移学习的图像分类增强器
java·人工智能·pytorch·python·深度学习·语言模型
计算机学姐2 小时前
基于SpringBoot的校园跑腿系统【数据可视化统计+原创精品】
java·vue.js·spring boot·后端·mysql·信息可视化·echarts
va学弟2 小时前
Java 网络通信编程(1):服务器多任务连接+广播消息实现
java·运维·服务器