应用分层和企业规范

news2024/5/18 19:42:38

目录

一、应用分层

1、介绍

(1)为什么需要应用分层?

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

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

高内聚:

低耦合:

2、代码重构

controller:表现层

service:业务逻辑层

dao:数据层

model:实体类

3、应用分层的好处

二、企业规范

三、学习Spring MVC的总结


        之前写了几个简单的练习(图书管理系统、留言板...),这些只是一点简单的开发,但代码也显得比较乱,下图是几个类的分区,如图:

        那如果要把完整的图书管理系统开发完了呢?那就会更加乱了。所以下面要学习应用分层,把代码管理好。

        应用分层类似公司的组织架构:

        公司初创阶段,人比较少,一个人会身兼数职,即做财务,又做人事等等。随着公司的逐渐壮大,会把岗位进行细分,会划为财务部门、人事部门、行政部门等等。

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

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

一、应用分层

1、介绍

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

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

(1)为什么需要应用分层?

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

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

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

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

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

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

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

        之前写的图书管理系统,就没有按照上述的设计思想,而是代码大杂烩,如图:

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

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

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

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

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

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

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

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

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

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

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

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

        MVC中的视图和控制器对应三层架构中的表现层。MVC中的模型对应三层架构中的业务逻辑层、数据层、实体类。

        二者都是从不同角度对软件工程进行了抽象。

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

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

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

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

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

高内聚:

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

低耦合:

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

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

        好比在公司里,不同部门之间的关联性要尽可能小,一个小部分发生问题了,要尽可能降低对其他部门的影响,这就是低耦合;而当一个部门里出现问题时,这个部门之间的员工关系要经可能的紧密,遇到问题一起解决、克服,这就是高内聚。

2、代码重构

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

controller:表现层

@RestController
@RequestMapping("/book")
public class BookController {
    @RequestMapping("/getBookList")
    public List<BookInfo> getBookList() {
        BookService bookService = new BookService();
        return bookService.getBookList();
    }
}
@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(!"admin".equals(userName) || !"admin".equals(password)) {
            return "账号或密码错误";
        }
        session.setAttribute("userName", userName);
        return "";
    }
}

原本这里面的数据也是要从数据库里拿的,还有逻辑判断,但是还没学到数据库的使用,先不管。

service:业务逻辑层

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;
    }
}

dao:数据层

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;
    }
}

model:实体类

@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;//状态的中文含义
}

3、应用分层的好处

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

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

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

(4)有利于标准化。


二、企业规范

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

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

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

常见命名风格:

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

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

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

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


三、学习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响应状态码。

3、JavaEE 学习阶段会涉及较多工具,插件的学习,来帮助我们提高开发效率,比如Postman、lombok、EditStarter,后面还会继续学习其他的工具或插件。


都看到这了,点个赞再走吧,谢谢谢谢谢

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

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

相关文章

【软件测试】测试用例设计方法

1. 等价类划分法1.1. 等价类划分法的定义1.2. 有效等价类和无效等价类1.3. 等价类划分法实例分析 2. 边界值分析法2.1. 边界值分析法的定义2.2. 边界点2.3. 边界值法实例分析 3. 判定表法3.1. 如何用判定表法设计测试用例3.2. 判定表法实例分析 4. 正交表法4.1. 什么是正交表4.…

模拟实现memcpy,memmove,memset,memcmp

memcpy void * memcpy ( void * destination, const void * source, size_t num ); 使用注意事项&#xff1a; 从source的位置向后复制num个字节数据到destination所指向的内存位置中。 这个函数遇到如果源空间和⽬标空间出现重叠&#xff0c;就得使⽤memmove函数处理。 …

纯血鸿蒙APP实战开发——自定义路由栈管理

介绍 本案例将介绍如何使用路由跳转返回时获取到来源页的模块名以及路径名&#xff0c;在实际场景中同一页面通常会根据不同来源页展示不同的UI。 使用说明 无特殊使用说明&#xff0c;其他使用说明参考动态路由的相关说明 实现思路 路由来源页的实现 新增来源页字段 ex…

【刷题篇】动态规划-二维费用的背包问题(十二)

文章目录 1、一和零2、盈利计划3、组合总和 Ⅳ4、不同的二叉搜索树(卡特兰数) 1、一和零 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#x…

vue快速入门(五十三)使用js进行路由跳转

注释很详细&#xff0c;直接上代码 上一篇 新增内容 几种常用的路由跳转方式演示 源码 App.vue <template><div id"app"><div class"nav"><!-- router-link 自带两个高亮样式类 router-link-exact-active和router-link-active区别&a…

AI代理架构的发展:从单一到多代理系统的演进及其影响分析

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

数字逻辑之“逻辑门电路”

一、基础知识 1、正逻辑和负逻辑 &#xff08;1&#xff09;基本的逻辑规定 1——“真”0——“假” &#xff08;2&#xff09;正逻辑和负逻辑 在实际的数字系统中&#xff0c;用数字信号&#xff08;逻辑电平U1&#xff0c;U2&#xff09;表示“真&#xff08;1&#xf…

FloodFill-----洪水灌溉算法(DFS例题详解)

目录 一.图像渲染&#xff1a; 代码详解&#xff1a; 二.岛屿数量&#xff1a; 代码详解&#xff1a; 三.岛屿的最大面积&#xff1a; 代码详解&#xff1a; 四.被围绕的区域&#xff1a; 代码详解&#xff1a; 五.太平洋大西洋水流问题&#xff1a; 代码详解&#x…

[leetcode] B树是不是A树的子结构

给定两棵二叉树 tree1 和 tree2&#xff0c;判断 tree2 是否以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 注意&#xff0c;空树 不会是以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 示例 1&#xff1a; 输入&#xff1a;tree1 [1,7,5], tree2 [6,…

Docker-compose部署LTC同步节点

1、下载ltc程序包&#xff0c;litecoin下载地址 下载页 mkdir /data/docker-compose/ltc cd /data/docker-compose/ltc https://github.com/litecoin-project/litecoin/releases/download/v0.21.3/litecoin-0.21.3-x86_64-linux-gnu.tar.gz2、编写dockerfile和bitcoin.conf b…

M2M vs. IoT?

有任何关于GSMA\IOT\eSIM\RSP\业务应用场景相关的问题&#xff0c;欢迎W: xiangcunge59 一起讨论, 共同进步 (加的时候请注明: 来自CSDN-iot). 连接设备已经开辟了创造价值和解决重大世界问题的广泛机会&#xff0c;例如可持续发展。 今天&#xff0c;我们网络设备的方式可…

tomcat打开乱码修改端口

将UTF-8改成GBK 如果端口冲突&#xff0c;需要修改tomcat的端口

智慧校园云平台源码,SaaS运营云平台(支持多学校、多校园使用)

智慧班牌系统&#xff0c;又称电子班牌系统&#xff0c;是一种基于互联网技术的综合管理工具。通过在教室内安装显示屏&#xff0c;并连接到学校管理系统&#xff0c;实现教学资源展示、信息发布、学生管理等多种功能的集成。该系统旨在加强学校班级文化建设和班级风采展示&…

Gitea 上传用户签名

在 Gitea 的用户管理部分&#xff0c;有一个 SSH 和 GPG 的选项。 单击这个选项&#xff0c;可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户&#xff0c;可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出&#xff0c;…

84、动态规划-完全平方数

思路 第一种递归方式&#xff1a; public static int numSquares3(int n) {if (n<2){return n;}return process(n);}private static int process(int rest) {if (rest<0){return 0;}int minrest;for (int i 2; i*i <rest ; i) {int countrest/(i*i);for (int j 1;…

初始Java篇(JavaSE基础语法)(6)(继承和多态)(下)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaSE 多态篇 目录 多态的概念 实现多态的条件 必须在继承体系下实现向上转型&#xff1a; 子类必须对父类中的方法进行重写&#xff1…

Wireshark CLI | 过滤包含特定字符串的流

问题背景 源自于和朋友的一次技术讨论&#xff0c;关于 Wireshark 如何查找特定字符串所在的 TCP 流&#xff0c;原始问题如下&#xff1a; 仔细琢磨了下&#xff0c;基于我对 Wireshark 的使用经验&#xff0c;感觉一步到位实现比较困难&#xff0c;所以想着说用 Wireshark C…

Tomcat启动闪退怎么解决(文末附终极解决方案)

AI是这么告诉我的 Tomcat启动时出现闪退问题可能由多种原因引起&#xff0c;以下是解决此类问题的一些通用方法&#xff1a; 检查环境变量&#xff1a; 确保已经正确设置了JAVA_HOME和JRE_HOME环境变量&#xff0c;并指向正确的Java安装路径。将Java的bin目录添加到系统的PATH…

用户中心(下)

文章目录 计划登录逻辑接口简单说明cookie和session写代码流程后端逻辑层控制层测试用户管理接口 前端简化代码对接后端代理 计划 开发完成后端登录功能 &#xff08;单机登录 > 后续改造为分布式 / 第三方登录&#xff09;✔开发后端用户的管理接口 &#xff08;用户的查询…

LLaMA详细解读

LLaMA 是目前为止&#xff0c;效果最好的开源 LLM 之一。精读 LLaMA 的论文及代码&#xff0c;可以很好的了解 LLM 的内部原理。本文对 LLaMA 论文进行了介绍&#xff0c;同时附上了关键部分的代码&#xff0c;并对代码做了注释。 摘要 LLaMA是一个系列模型&#xff0c;模型参…