MVC与三层架构分层

news2024/11/15 20:59:14

1. 应用分层

        应用分层类似公司的组织架构。我们进行项目开发时,最开始功能简单,前后端放在一起开发,但随着项目功能的复杂,项目会被前端和后端不同的团队接手,甚至更细粒度的团队。甚至后端开发也会根据功能再进行细分。MVC就是其中的一种拆分方式。

        随着后端人员不再涉及前端,后端开发又有了新的分层方式。

1.1 介绍

        阿里开发手册中,关于工程结构部分,定义了常见工程的应用分层结果,如下图所示:

        应用分层是一种软件开发设计思想,它将应用程序分成N个层次,这N个层次分别负责各自的职责,多个层次之间协同提供完整的功能。根据项目的复杂度,把项目分成三层,四层或者更多层。其中常见的MVC设计模式,就是应用分层的一种具体体现。

  1.1.1 为什么需要应用分层

        在最开始的时候,为了让项目快速上线,通常是不考虑分层的。但是随着业务越来越复杂,大量的代码混在一起,会出现逻辑不清楚、代码扩展性插、改一处导致处处改等问题。

1.1.2 如何分层?(三层架构)

        前面学习了MVC,把整体分成了三个层次:View(视图)、Controller(控制器)、Model(模型),也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好的实现了表现和逻辑的解耦。是一种标准的软件分层架构。如图:

        当前更主流的开发方式是 “前后端分离” 的方式,后端开发工程师不再需要关注前端的实现,所以对于Java后端开发者,又有了一种新的分层架构:把整体架构分为表现层、业务逻辑层、数据层。这种分层方式也称之为 “三层架构”。

1、表现层:就是展示数据结果和接受用户指令的,是最靠近用户的一层。

2、业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现。

3、数据层:负责存储和管理应用程序相关的数据。

       可以看到, 咱们前⾯的代码, 并不符合这种设计思想, ⽽是所有的代码堆砌在⼀起,如下图所示:
 

         按照上面的层次划分,Spring MVC 站在后端开发人员的角度上,把上述代码划分为三个部分:

1、请求处理:响应数据:负责接受页面的请求,给页面响应数据。

2、逻辑处理:负责业务逻辑处理的代码。

3、数据访问:负责业务数据的维护操作,包括增、删、改、查。

        这三个部分,在Spring的实现中,都有体现,如下图所示:

 1、Controller:控制器。接收前端发送的请求,对请求进行处理,并且响应数据。

2、Service:业务逻辑层。处理具体的业务逻辑。

3、Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

1.2 MVC和三层架构的区别和联系

        从概念上来说,二者都是软件工程领域中的架构模式。

        1、MVC架构模式由三部分组成:View(视图)、Controller(控制器)、Model(模型)

        2、三层架构将业务应用划分为:表现层、业务逻辑层、数据访问层

        MVC中的视图和控制器对应三层架构中的表现层。MVC中的模型对应三层架构中的业务逻辑层、数据层、实体类;二者架构图如下所示:

         由上图可知,二者都是从不同角度对软件工程进行了抽象。

        MVC模式强调数据和视图分离,将数据展示和数据处理分开。控制器是它们之间的桥梁,通过控制器对两者进行组合。

        三层架构强调不同维度数据处理的高内聚和低耦合,将交互界面、业务处理、数据库操作的逻辑分开。

        二者开发角度角度不同,故此也就谈不上互相替代了,在日常的开发中,可以经常看到两种共存的情况。比如我们设计模式的时候往往也会拆分出业务逻辑层(Service层)和数据访问层(dao层)。

        但两者的目的都是相同的:都是为了“解耦,分层,代码复用”。

1.3  软件设计原则:高内聚低耦合

1.3.1 高内聚

        一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 “高内聚”。

  1.3.2 低耦合

        软件中各个层、模块之间的依赖关联程序越低越好。修改一处代码,其他模块的代码改动越少越好。

        那么高内聚和低耦合矛盾吗?其实不矛盾,高内聚是指一个模块中的各个元素之间的紧密程度,低耦合是指各个模块之间的精密程度。如图:

          好比在大明1566朝堂里,清流和严党之间的关联性要尽可能小,严党出问题了,清流党要尽可能减少两党之间的关系,反之被牵连,这就是低耦合;而当严党自己内部出了问题时,整个党派之间的所有成员要紧密的团结在一起,一起解决、克服已经出现的问题,这就是高内聚。

2、代码重构

        上篇写了图书管理系统,但是代码非常乱,现在进行代码重构,先创建对应包的路径,如图:

2.1 表现层

        接收前端发送的请求,对请求进⾏处理,并响应数据;

package com.example.zxslzw2014_8_11.controller;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public String login(String userName, String password, HttpSession session) {
        //1、校验参数
        //2、校验密码是否正确
        //3、返回响应结果
        System.out.println(userName + " " + password);
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return "用户名或者密码为空";
        }
        if(!"smy".equals(userName) || !"111".equals(password)) {
            return "账号或密码错误";
        }
        session.setAttribute("userName", userName);
        return "登录成功";
    }
}
package com.example.zxslzw2014_8_11.controller;

import com.example.zxslzw2014_8_11.model.BookInfo;
import com.example.zxslzw2014_8_11.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("/getBookList")
    public List<BookInfo> getBookList() {
        BookService bookService = new BookService();
        return bookService.getBookList();
    }
}

 2.2 service业务逻辑层

package com.example.zxslzw2014_8_11.service;

import com.example.zxslzw2014_8_11.dao.BookDao;
import com.example.zxslzw2014_8_11.model.BookInfo;

import java.util.List;

public class BookService {
    public List<BookInfo> getBookList() {
        BookDao bookDao = new BookDao();
        List<BookInfo> bookInfos = bookDao.mockData();
        for(BookInfo bookInfo : bookInfos) {
            if(bookInfo.getStatus() == 2) {
                bookInfo.setStatusCN("不可借阅");
            } else {
                bookInfo.setStatusCN("可借阅");
            }
        }
        return bookInfos;
    }
}

 2.3 dao:数据访问层

        数据访问层: 负责数据访问操作,包括数据的增、删、改、查

package com.example.zxslzw2014_8_11.dao;

import com.example.zxslzw2014_8_11.model.BookInfo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class BookDao {
    public List<BookInfo> mockData() {
        //理论上应该从数据库中获取数据,当前采用mock方式
        List<BookInfo> bookInfos = new ArrayList<>();
        for (int i = 1; i <= 15; i++) {
            BookInfo bookInfo = new BookInfo();
            bookInfo.setId(i);
            bookInfo.setBookName("图书" + i);
            bookInfo.setAuthor("作者" + i);
            bookInfo.setNum(i * 2 + 1);
            bookInfo.setPrice(new BigDecimal(i * 3));
            bookInfo.setPublishName("出版社" + i);
            if(i % 5 == 0) {
                bookInfo.setStatus(2);
//                bookInfo.setStatusCN("不可借阅");
            } else {
                bookInfo.setStatus(1);
//                bookInfo.setStatusCN("可借阅");
            }
            bookInfos.add(bookInfo);
        }
        return bookInfos;
    }
}

2.4 model:实体类

package com.example.zxslzw2014_8_11.model;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class BookInfo {
    private Integer id;
    private String bookName;
    private String author;
    private Integer num;
    private BigDecimal price;
    private String publishName;
    private Integer status;//1-可借阅   2-不可借阅
    private String statusCN;//状态的中文含义
}

2.5  应用分层的好处

(1)降低层与层之间的依赖,结构更加的明确,利于各层逻辑的复用。

(2)开发人员可以只关注整个结构中的其中某一层,极大地降低了维护成本和维护时间。

(3)可以很容易的用新的实现来替换原有层次的实现。

(4)有利于标准化。

3.企业规范

1、类名使用大驼峰风格,但以下情形例外:DO / BO / DTO / VO / AO。

2、方法名、参数名、成员变量、局部变量统一使用小驼峰风格。

3、包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。

        常见命名风格:

大驼峰:所有单词首字母都需要大写,又叫帕斯卡命名发,比如:UserController

小驼峰:除了第一个单词,其他单词首字母大写,比如:userController。

蛇形:用下划线(_)作用单词间的分隔符,一般小写,又叫下划线命名法,比如user_controller。

串形:用短横线(-)作用单词间的分隔符,又叫脊柱命名法,例如:user-controller。

4. 学习Spring MVC的总结

1、学习Spring MVC,其实就是学习各种Web开发需要用到的注解:

a、@RequestMapping:路由映射

b、@RequestParam:后端参数重命名

c、@RequestBody:接收JSON类型的参数

d、@PathVariable:接收路径参数

e、@RequestPart:上传文件

f、@ResponseBody:返回数据

g、@CookieValue:从Cookie中获取值

h、@SessionAttribute:从Session中获取值

i、@RequestHeader:从Header中获取值

j、@Controller:定义一个控制器,Spring框架启动时加载,把这个对象交给Spring管理。默认返回视图。

k、@RestController:@ResponseBody + @Controller 返回数据

2、Cookie和Session都是会话机制,Cookie是客户端机制,Session是服务端机制。二者通过SessionId来关联。Spring MVC 内置 HttpServletRequest,HttpServletResponse两个对象。需要使用时,直接在方法中添加对应参数即可,Cookie和Session可以从HttpServletRequest中来获取,也可以直接使用HttpServletResponse设置Http响应状态码。

ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!

本文的封面来自:bilibili苏杉杉的pv,侵权删 url:https://www.bilibili.com/video/BV1vo4y167eh/?spm_id_from=333.999.0.0&vd_source=866da5be2ef0ddd213b053523da53138
————————————————

电子签名:上嘉路

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2048745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

把VTK窗口嵌入到Qt的窗口中显示(二)

把VTK窗口嵌入到Qt的窗口中显示(二) 一、控件拖动 之前的文章介绍了,如何通过拖动一个控件,然后提升这个控件为QVTKWidget,然后来显示点云信息。 把VTK窗口嵌入到Qt的窗口中显示(一) 其实我们还可以直接通过代码来实现。我们打开QVTKWidget的代码可以看到,这个类就…

函数序列的逐点收敛和一致收敛的理解

目录 1. 逐点收敛(Pointwise Convergence) 1.1 逐点收敛定义 1.2 对逐点收敛的理解 1.3 举例说明 2. 一致收敛(Uniform Convergence) 2.1 一致收敛定义 2.2 对一致收敛的理解 2.3 举例说明 1. 逐点收敛(Pointwise Convergence) 1.1 逐点收敛定义 我们令 为…

无人机里的陀螺仪/加速器/气压计/GPS详解

陀螺仪 是一种用于测量和控制无人机姿态的重要传感器。它通过检测无人机的旋转运动来提供准确的方向和角度信息。 加速度计 用于提供无人机在XYZ三轴方向所承受的加速力。它也能决定无人机在静止状态时的倾斜角度。 气压计 通过测量大气压力来估算无人机的高度。随着高度的…

疫情隔离酒店管理系统的开发--论文pf

TOC springboot395疫情隔离酒店管理系统的开发--论文pf 绪 论 1.1研究背景与意义 当前&#xff0c;我国的常态化防控正处于迅速发展阶段&#xff0c;管理人员与疫情防控进一步标准化&#xff0c;需各酒店等生活服务场所加强管理&#xff0c;使用健全的信息系统对防控工作进…

Windows环境在使用Pycharm设置Python解译器时提示找不到Python打包工具,安装打包工具错误提示解决方法

问题现像如下 截图&#xff1a; 解决方法&#xff1a; 第一步&#xff1a;在CMD命令行输入&#xff1a; python -m ensurepip --default-pip 安装distutils 第二步&#xff1a;检查和安装setuptools和wheel&#xff1a; python -m pip install --upgrade setuptools wheel…

如何搭建软件测试环境?

关于如何搭建测试环境&#xff0c;也是面试会经常问到的一个问题&#xff0c;一般常见于一些创业公司&#xff0c;因为测试环境不够完善&#xff0c;可能会遇到搭建环境这个问题。 一般来说&#xff0c;测试环境搭建都属于运维的工作范畴&#xff0c;但是可能有些创业公司就没有…

日拱一卒(5)——leetcode学习记录:路经总和

一、任务 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…

【秋招笔试】8.17饿了么秋招第一场-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…

Unity图形系统

Unity的图形系统是一个复杂且功能强大的模块&#xff0c;它支持多种渲染技术和API&#xff0c;能够满足从移动设备到高端游戏机和桌面平台的各种需求。以下是关于Unity图形系统的详细解析&#xff1a; 渲染流程与技术 Unity的渲染流程可以分为应用程序阶段&#xff08;CPU&…

公开测评:文件防泄密系统哪家好|4款文件防泄密软件推荐

在文件防泄密系统领域&#xff0c;有多款软件以其高效、安全和全面的功能脱颖而出&#xff0c;为企业数据保护提供了有力支持。以下是四款值得推荐的文件防泄密软件&#xff0c;它们各具特色&#xff0c;能够满足不同企业的数据安全需求。 1. 安企神软件 7天试用版https://wor…

Ubuntu | 更换 Geth 版本

参考博客&#xff1a;VMware 虚拟机下 Ubuntu 中 geth 和 truffle 更换版本解决 写在前面&#xff1a;我按照参考博客的方法添加了环境变量&#xff0c;但是报错 geth 命令不存在&#xff0c;因此我换了一种方法。 重新安装 1.10.8-stable 版本的 Geth ① 移除当前已经安装的…

Nginx核心配置详解

一、配置文件说明 nginx官方帮助文档&#xff1a;nginx documentation nginx的配置文件的组成部分&#xff1a; 主配置文件&#xff1a;nginx.conf子配置文件: include conf.d/*.conffastcgi&#xff0c; uwsgi&#xff0c;scgi 等协议相关的配置文件mime.types&#xff1a;…

无人机之螺旋桨篇

一、工作原理 根据牛顿第三定律&#xff0c;无人机受到向上的力&#xff0c;这是因为桨叶对空气施加了一个向上的力。螺旋桨产生的升力是指使飞机或无人机升空的力量。升力的大小取决于机翼或螺旋桨的倾斜角度。当空气流过机翼或螺旋桨时&#xff0c;其速度在顶部增加&#xff…

计算机毕业设计 学生就业信息系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

计算数学精解【14】-Maxima计算精解【2】

文章目录 基础符号计算 参考文献 基础 符号计算 分数&#xff08;有理数&#xff09;基本运算 无理数 小数及位数 bfloat提供任意精度实数,fpprec控制小数位数 代数展开 ratsimp完成通分 因式分解 参考文献 1.《Maxima在线性代数的应用》 2. https://maxima.sourcefor…

Linux内核之网络套接字

文章目录 前言一、TCP4层模型和OSI7层模型OSI 7层模型TCP/IP 4层模型比较 二、套接字概念三、sockaddr_in和sockaddr结构体sockaddr_insockaddr区别 四、协议中的数据划分数据划分和首部添加流程数据接收与解析流程流程图 前言 一、TCP4层模型和OSI7层模型 OSI 7层模型 物理…

XSS Game练习

1.Ma Spaghet 直接get传参 ?somebodyaaaa直接使用img标签 ?somebody<img%20src1%20onerror"alert(1337)">官方文档 应使用innertext&#xff0c;安全性更高 2.Jefff 通过代码可以知道是通过eval的代码执行&#xff0c;setTimeout中的内容表示在一秒后执行…

avalonia学习之布局组件

border 边框控件用边框和背景装饰一个&#xff08;单个&#xff09;子控件。它还可用于显示圆角。 属性 属性描述Background背景颜色。BorderBrush边框颜色。BorderThickness边框线粗细&#xff08;整数&#xff09;。CornerRadius所有四个角的半径&#xff08;一个值&#…

解决com.google.android.play:core:1.10.3在10.1号之后targetSDK升到34的问题

implementation com.google.android.play:core:1.10.3或者这样的 升到android14 之后可能提审的时候都会遇到这个问题&#xff0c;解决方法如下&#xff1a; implementation com.google.android.play:asset-delivery:2.2.2 implementation com.google.android.play:app-update…

刀锋利器:Knife4j助你轻松驾驭API文档

文章目录 整合Knife4j引入依赖编写配置文件 法①编写配置文件 法②配置名词解释注解三兄弟 : ApiOperation、ApiParam、ApiModel 启动项目, 访问Knife4j测试Knife4j优点支持全局参数支持离线文档支持API搜索 **技术派项目源码地址 : ** **Gitee : **技术派 - https://gitee.co…