当前位置: 首页 > article >正文

JavaWeb三层架构

        我们先来看一个请求响应类的代码,实现了从resource中读取user.txt文件获取用户信息封装,然后响应前端展示的功能。

package com.wzb.Controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pojo.User;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户信息Controller
 */
@RestController
public class UserController {

    @RequestMapping("/list")
    public String list() {
        // 1.加载user.txt文件获取用户信息,并将每一行的信息封装到ArrayList集合中,一行信息就是一个字符串元素
        // 因为类和resource在编译之后是在一起的,所以说通过获得本类的类加载器,调用getResourceAsStream方法(参数就是需要的文件名)
        // 返回该文件的输入流,可以避免使用绝对路径获得文件的输入流
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        // 使用hutool中的IoUtil,便捷的读文件输入流的内容,需要指定编码,并返回一个集合,集合中的每一个元素就是文件的一行内容
        ArrayList<String> lines = IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());

        // 2.解析集合,获取用户属性,将属性封装成用户再用集合收集
        List<User> userList = lines.stream().map(line -> {
            String[] parts = line.split(","); // 用","分割字符串,得到每一个属性
            Integer id = Integer.parseInt(parts[0]);
            String username = parts[1];
            String password = parts[2];
            String name = parts[3];
            Integer age = Integer.parseInt(parts[4]);
            // 使用DateTimeFormatter类限定时间的格式,并按照该格式将String类型的时间字符串解析为LocalDateTime对象
            LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            return new User(id, username, password, name, age, updateTime);
        }).collect(Collectors.toList());

        //3.响应数据
        // 使用hutool中的JSONUtil类,将集合解析为json字符串返回,还可以使用setDateFormat方法设置json的时间格式
        return JSONUtil.toJsonStr(userList, JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss"));
    }
}

        

        此时,这个代码已经可以实现业务功能了,但是其实还是可以进行优化的:因为进行响应、获取数据、逻辑处理都在一个类中完成,假如说业务逻辑稍微变化,那么需要修改的地方就太多了,维护起来十分困难,用专业的术语来讲就是高耦合。这并不符合软件设计的原则——“高类聚、低耦合”。所以说一般在企业开发中使用三层架构的方式来实现分层解耦,从而达到软件设计的原则,增强程序的复用性、可维护性。

        三层架构

        Controller直接接收浏览器发送的请求,并调用Service进行处理;Service调用Dao获取数据;Dao从数据库中获取数据返回给Service,Service对Dao返回的数据进行逻辑处理返回给Controller;最后Controller将处理好的数据响应给前端。项目中一般会有多个Controller、Service、Dao,所以说需要先定义好对应的接口,再按照对应的业务逻辑编写其实现类(面向接口编程)。

        第一层:Controller(接收请求、响应数据)

        Controller是控制层,主要职责是接收前端发送的请求,对请求进行处理,并给前端响应数据,这一层需要和Service关联。 通过三层架构修改代码,使得Controller中的代码只有接收请求和响应数据的功能:

package com.wzb.controller;

import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.wzb.pojo.User;
import com.wzb.service.UserService;
import com.wzb.service.impl.UserServiceImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {

    private final UserService userService = new UserServiceImpl();
    private final List<User> userList = userService.findUser();

    @RequestMapping("/list")
    public String list() {
        return JSONUtil.toJsonStr(userList, JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

}

        

        第二层:Service(逻辑处理)

        Service是业务逻辑层,主要的职责是处理具体的业务逻辑,这一层需要和Dao层关联;先在Dao层中获取了数据,再根据业务逻辑进行数据处理,将处理好的数据返回给Controller层。Service层的功能只有按照逻辑处理数据:

package com.wzb.service.impl;

import com.wzb.dao.UserDao;
import com.wzb.dao.impl.UserDaoImpl;
import com.wzb.pojo.User;
import com.wzb.service.UserService;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Service层实现类
 *
 */
public class UserServiceImpl implements UserService {

    private final UserDao userDao = new UserDaoImpl();
    private final List<String> lines = userDao.findUser();

    public List<User> findUser() {
        List<User> userList = lines.stream().map(line -> {
            String[] parts = line.split(",");
            Integer id = Integer.parseInt(parts[0]);
            String username = parts[1];
            String password = parts[2];
            String name = parts[3];
            Integer age = Integer.parseInt(parts[4]);
            LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            return new User(id, username, password, name, age, updateTime);
        }).collect(Collectors.toList());
        return userList;
    }
}

        第三层:Dao(数据访问)

        Dao(Data Access Object 持久层),主要的职责是负责数据访问操作,包括数据的CRUD,这一层需要和数据库关联。Dao层在数据库中(或者其他数据源)获取数据之后,封装到集合中(或者不封装),直接返回到Service层,Service层进行处理。Dao层只负责和数据库交互获取数据。

package com.wzb.dao.impl;

import cn.hutool.core.io.IoUtil;
import com.wzb.dao.UserDao;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * Dao层的实现类
 *
 */
public class UserDaoImpl implements UserDao {

    @Override
    public List<String> findUser() {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
        return IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());
    }
}

        这样通过三层架构,就将原来一个类中的代码、一个类实现的功能,分工给了三个类,这样每一层各司其职,代码的维护性、可复用性大大提高,也便于分层解耦。 


http://www.kler.cn/a/412612.html

相关文章:

  • ubuntu 安装 docker 记录
  • Redis持久化、主从及哨兵架构详解
  • 【青牛科技】D1671 75Ω 带4级低通滤波的单通道视频放大电 路芯片介绍
  • JavaScript核心语法(3)
  • 文件上传upload-labs-docker通关
  • 架构-微服务架构
  • Flutter 开发环境—Linux
  • RabblitMQ 消息队列组件与 libev事件驱动库
  • 【Petri网导论学习笔记】Petri网导论入门学习(十一) —— 3.3 变迁发生序列与Petri网语言
  • Leecode刷题C语言之交替组②
  • 鸿蒙面试 --- 性能优化(精简版)
  • K8s调度器扩展(scheduler)
  • 小程序-基于java+SpringBoot+Vue的微信小程序养老院系统设计与实现
  • C语言中使用动态内存
  • SpringBoot集成minio,并实现文件上传
  • Flutter:封装发送验证码组件,注册页使用获取验证码并传递控制器和验证码类型
  • java内存管理介绍
  • 选择正确的网络代理模式:全面指南与实际应用示例
  • SpringBoot框架助力欢迪迈手机商城快速开发
  • C++11 http服务端和客户端库cpp-httplib
  • react 前端最后阶段静态服务器启动命令
  • win、linux等环境下python输出cpu、gpu、avx等硬件信息
  • WindTerm 开源工具基础使用
  • 【大数据学习 | Spark-SQL】关于RDD、DataFrame、Dataset对象
  • Django在fitler过滤不等于的条件
  • 移门缓冲支架:保护您的家