【基于三层架构的人员管理系统—控制台】



前言

  本文章下的代码中有一些个人在学习过程中的注解,可以参考理解,说法有误可指正。

一、人员管理系统概述

  基于分层思想去构建一个在控制台运行的管理系统,实现对人员的简易管理。

  • [ 人员管理系统]
  • 学生管理系统
    对学生信息进行管理
    完成对学生信息的增删查改的操作
  • 老师管理系统
    对老师信息进行管理
    完成对老师信息的增删查改的操作

二、分层

2. 1 三层架构概述

​ 三层架构 (3-tier architecture) : 在软件体系架构中,自上而下将整个业务应用划分为三层:

  • 表示层(User lnterface layer): 主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。
  • 业务逻辑层(Business Logic Layer): 主要实现业务逻辑。业务逻辑具体包含: 验证、计算、业务规则等等,UI层(表示层)和DAL层(数据访问层)之间的桥梁。
  • 数据访问层(Data acess layer): 主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。

2. 2 为什么分层

  分层思想的目的即为了实现高内聚低耦合

内聚:是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事,它描述的是模块内的功能联系。

耦合: 是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。

**高内聚低耦合:**是软件工程中的概念,是判断软件设计好坏的标准,主要用于程序的面向对象的设计,主要看类的内聚性是否高,耦合度是否低。(高内聚:模块的聚合度高,低耦合:模块之间的关联性低)

高内聚低耦合目的是使程序模块的可重用性、移植性大大增强

通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。

低内聚高耦合如下图:
在这里插入图片描述
高内聚低耦合如下图:
在这里插入图片描述

  • [ 总结:]
  • 高内聚(模块的规划和排列很整齐)低耦合(模块之间没有杂乱的排线,只通过引脚的联系)

2. 3 人员管理系统分层

  • Student类:标准学生类,封装键盘录入的学生信息(id,name,age,birthday)

  • Student Dao类 Dao :(Data Access Object 缩写) 用于访问存储数据的数组或集合;——数据访问层

  • Student Service类:用来进行业务逻辑的处理(例如: 判断录入的id是否存在);——业务逻辑层

  • Student Controller类:和用户打交道(接收用户需求,采集用户信息,打印数据到控制台);——表示层

三、分包

2.1 分包思想概述

​  如果将所有的类文件都放在同一个包下,不利于管理和后期维护,所以,对于不同功能的类文件,可以放在不同的包下进行管理。

2.2 包的概述


  • 本质上就是文件夹
  • 创建包
    多级包之间使用"."进行分割- 包的命名规则:字母都是小写

2.3 包的注意事项

  • package语句必须是程序的第一条可执行的代码
  • package语句在一个iava文件中只能有一个
  • package声明表示该类的所属关系,如果没有package则默认表示无包名
  • 所有包的操作都由idea去完成

2.4 类与类之间的访问

  • 同一个包下的访问

    不需要导包,直接使用即可

  • 不同包下的访问

    1. import 导包后访问;
      在这里插入图片描述
    2. 通过全类名 (包名 +类名) 访问注意: import、package 、class 三个关键字的摆放位置存在顺序关系。
      在这里插入图片描述
    3. package 必须是程序的第一条可执行的代码import 需要写在 package 下面class 需要在 import 下面:

四、学生管理系统

3.1 需求说明

  • 添加学生:键盘录入学生信息(id,name,age,birthday)使用数组存储学生信息,要求学生的id不能重复
  • 删除学生:键盘录入要删除学生的id值,将该学生从数组中移除,如果录入的id在数组中不存在,需要重新录入
  • 修改学生:键盘录入要修改学生的id值和修改后的学生信息将数组中该学生的信息修改,如果录入的id在数组中不存在,需要重新录入
  • 查询学生: 将数组中存储的所有学生的信息输出到控制台

3.2 实现步骤

  • 环境搭建实现步骤
包(com.wedu.staff.manager)存储的类作用
com.staff.manager.domainStudent.java封装学生信息
com.staff.manager.daoStudentDao.java访问存储数据的数组,进行增删改查 (库管)
.serviceStudentService.java业务的逻辑处理 (业务员)
.controllerStudentController.java和用户打交道 (客服接待)
.entryStaffManagerEntry.java程序的入口类,提供一个main方法
  • 菜单搭建实现步骤

  • 需求

    • XX人员管理系统菜单搭建
    • 学生管理系统菜单搭建
  • 实现步骤

    1. 展示欢迎页面,用输出语句完成主界面的编写
    2. 获取用户的选择,用Scanner实现键盘录入数据
    3. 根据用户的选择执行对应的操作,用switch语句完成操作的选择

3.3 具体实现

  • [ 分包] 如图
    在这里插入图片描述
  • [ 分层] 如图
    在这里插入图片描述
  • 菜单界面即功能选择
import java.util.Scanner;
//人员管理系统的交互界面
//程序主函数的入口
public class StaffManagerEntry {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("-------欢迎来到人员管理系统-------");
            System.out.println("请选择想进行的操作(1-3):");
            System.out.println("1.学生管理  2.教师管理  3.退出");
            String choice = sc.next();
            switch (choice) {
                case "1":
                    //调用学生管理系统
                    //创建一个新的学生表示层对象——新的StudentController对象
                    StudentController studentController = new StudentController();
                    //用新的学生表现层对象调用StudentController类中的start()方法
                    studentController.start();
                    break;
                case "2":
                    //调用老师管理系统,与学生管理系统同理
                    TeacherController teacherController = new TeacherController();
                    teacherController.start();
                    break;
                case "3":
                    //退出
                    //另一种方法退出死循环,调用System里的一个exit()方法
                    System.out.println("欢迎再次使用!");
                    System.exit(0);//让JVM停止运行
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入!!");
            }
        }
    }
}

进入学生管理系统界面与主菜单差不多,但会在相应功能选择处调用相应的方法,后面会

            switch (choice) {
                case "1":
                    //调用添加学生的方法
                    addStudent();
                    break;
                case "2":
                    //调用删除学生的方法
                    deleteStudentById();
                    break;
                case "3":
                    //调用修改学生的方法
                    updateStudent();
                    break;
                case "4":
                    //调用查看学生的方法
                    findAllStudent();
                    break;
                case "5":
                    //退出
                    //此时不能调用System里的exit()方法来退出程序,因为我们目的只是为了退出学生管理系统的模块,而不是退出整个人员管理系统
                    System.out.println("欢迎再次使用!");
                    break StuLoop;//退出学生管理系统
                default:
                    System.out.println("您的输入有误,请重新输入!!");
            }
  • 添加功能及添加功能优化(判断id是否存在)实现步骤
      通过addStudent()方法
    需要利用三层架构,在三个层面都去利用到addStudent()这个方法来实现我们的这个操作
    • [表示层 ]
 public void addStudent() {
        String id;
        //提示用户键盘录入想要添加的学生的各项信息
        System.out.println("请输入学生信息:");
        while (true) {
            System.out.println("输入学生的学号:");
            id = sc.next();
            //判断是否有重复的学生id
            //创建一个新的业务逻辑层对象,来传递学生的id进行逻辑判断

            boolean res = studentService.isExists(id);//用res接收业务逻辑层中IsExists()方法运行结束的返回值
            //IsExists()方法:调用数据访问层中的findAllStudent()方法获取到学生数组
            //使id与学生数组中的id进行比较,从而判断id是否存在,存在则提示用户重新输入,若不存在则继续进行添加操作

            //判断用户录入的id在数组中是否存在
            if (res) {//存在-true
                System.out.println("您输入的学号已存在,请重新输入:");
            } else {//不存在-false
                break;//跳出死循环,继续进行添加操作
            }
        }

        //
        Student student =inputStudentinfo(id);

        //创建一个新的业务逻辑处理(StudentService)的对象
        //在StudentService类中写一个针对添加学生的addStudent()方法,来对新的学生对象student作出一些逻辑处理,并做一些对接
        //创建一个新的业务逻辑层对象,来传递学生对象,从而进行添加操作
        StudentService studentService = new StudentService();
        boolean result = studentService.addStudent(student);
        if (result) {
            System.out.println("添加成功!!");
        } else {
            System.out.println("添加失败!!");
        }
    }
  • [业务逻辑层 ]
public boolean isExists(String id) {
        Student[] students=studentDao.findAllStudent();//调用数据访问层中获取学生数组的方法
        //findAllStudent()该方法应该返回一个数组,用student接收
        boolean res=false;//定义一个boolean类型的变量res初始为false
        for (int i = 0; i < students.length; i++) {
            //如果添加第一个学生时,此时学生数组为null,用户输入的id与null是无法比较的,因此会出现空指针异常
            //解决:加一个条件判断,判断新的

            if(students[i]!=null) {
                if (students[i].getId().equals(id)) {//判断存不存在相同id
                    res = true;//若学生数组存在相同id,就改变res的值为true
                    break;//终止循环,执行循环外的语句
                }
            }
        }
        return res;
    }
//添加学生在业务逻辑处的方法addStudent
    public boolean addStudent(Student student){
        //判断id是否存在——在下面IsExists()方法中实现
        //将接受到的Student类中student学生对象传给数据访问层StudentDao类
        //等待StudentDao类保存数据并返回成功与否(用Boolean值进行接收)
        //将其结果(boolean值)又再返回给表示层StudentController类

        boolean result=studentDao.addStudent(student);
        return result;
    }
  • [数据访问层 ]
 public boolean addStudent(Student student){
        //创建一个容器,用来存储被传进来的学生对象,并进行添加操作
        //进行添加操作首先:因为数组中没有存放学生对象时,里面的初始值都为null
        //              要想添加学生对象,得先判断数组中还有没有空间可以存放,因此利用null值来判断
        //              如果数组中找得到为null的值,就把该值的下标索引赋给index变量
        //              进而实现添加操作

        int index=-1;//定义一个用来判断数组students中还有没有null值的变量

        //遍历数组找第一个null值,并将该值的下标索引赋给index变量
        for (int i = 0; i < students.length; i++) {
            if (students[i] == null) {
                index = i;
                break;//如果不加break就相当于添加学生时是从数组的末尾开始存入数据,因此打印数据时会从最后一个数据开始打印;
                //反之从数组的第一个位置存入,打印时的顺序就是学号的顺序
            }
        }

        //对index进行判断,如果不为-1,才将学生对象的信息存储到数组里面,并返回相应的Boolean类型的结果
        if(index==-1){
            System.out.println("暂无空间存放学生,请稍后再试!");
            return false;
        }else {
            students[index]=student;
            //boolean result = true;
            return true;
        }
    }
  • 查询功能实现步骤
    • [表示层 ]
//查看学生
    public void findAllStudent() {
        Student[] students = studentService.findAllStudent();
        if (students == null) {
            System.out.println("查无信息!!");
            return;
        } else {
            System.out.println("学号\t\t姓名\t\t年龄\t\t生日");
            for (int i = 0; i < students.length; i++) {
                Student stu = students[i];
                if(stu!=null){
                    System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t" + stu.getBirthday());
                }
            }
        }
    }
  • [业务逻辑层 ]
public Student[] findAllStudent() {
        //调用数据访问层studentDao类中的findAllStudent()方法获取学生数组
        //并新建一个学生数组(在StudentService的findAllStudent()方法中),用于接收从Dao中获取到的学生数组的数据
        Student[] students=studentDao.findAllStudent();

        boolean res=false;//定义一个布尔类型的变量res,用来判断数组中存不存在学生信息,假设数组中没有学生数据,则返回null

        for (int i = 0; i < students.length; i++) {
            //判断该学生数组中存不存在数据,若存在数据则令res=true,只要找到存在一条数据,即可证明就可以跳出循环进行下一步判断
            if(students[i]!=null){
                res=true;
                break;
            }
        }
        //判断res的值,存在数据——true,并返回学生数组给表示层,反之——false,就返回null值给表示层
        if (res){
            return students;
        }else {
            return null;
        }
    }
  • [数据访问层 ]
    //获取所有学生数组,用于被其他层调用进行相应的操作:查询和判断比较
    public Student[] findAllStudent() {
        return students;
    }
  • 删除功能实现步骤
    • [表示层 ]
    public void deleteStudentById() {
        String delId=inputStudentId();

        //调用业务逻辑层中的方法进行删除学生
        studentService.deleteStudentById(delId);
        System.out.println("删除成功!");
    }
  • [业务逻辑层 ]
    public void deleteStudentById(String delId) {
        studentDao.deleteStudentById(delId);
    }
  • [数据访问层 ]
    //进行删除操作,找到与用户录入id相同的学生id的索引位置,将其位置的数据重置为null,就完成了删除
    public void deleteStudentById(String delId) {
        int deleteindex=getIndex(delId);//将查找学生id的功能另写一个方法,通过方法调用实现,获取到id在数组中索引的位置
        if(deleteindex!=-1){
            students[deleteindex]=null;
        }
    }
  • 修改功能实现步骤
    • [表示层 ]
public void updateStudent() {
        String updateId=inputStudentId();
        //进行修改操作
        //调用录入学生的信息的方法inputStudentinfo(),创建新的学生对象接收方法的返回值
        Student updatestudent=inputStudentinfo(updateId);

        //调用业务层的方法updateStudent(),修改学生并提示修改成功
        studentService.updateStudent(updateId,updatestudent);
        System.out.println("修改成功!");
    }
  • [业务逻辑层 ]
    public void updateStudent(String updateId, Student updatestudent) {
        studentDao.updateStudent(updateId,updatestudent);
    }
  • [数据访问层 ]
    public void updateStudent(String updateId, Student updatestudent) {
        int updateindex=getIndex(updateId);//调用查找id索引值的方法,找到需要修改的学生id的索引值
        if(updateindex!=-1){
            students[updateindex]=updatestudent;//使用传入进来的新的学生对象updatestudent进行替换
        }
    }
  • 系统优化
    • 把updateStudent()方法和deleteStudentById()方法中录入学生id代码抽取到一个方法(inputStudentld)中
      • 该方法的主要作用就是录入学生的id,方法的返回值为String类型
//用户录入学生id,返回一个String类型的id值
    private String inputStudentId() {
        String id;
        while (true){
            System.out.println("请输入学生的学号:");
            id= sc.next();
            boolean res=studentService.isExists(id);
            if(res){//res——true:存在,继续进行操作,跳出死循环(如果用户输入的学号不存在,为了能让用户重新输入)
                break;
            }else {//res——false:不存在,提示用户重新输入,直到判断出用户录入的id存在我们的学生数组中
                System.out.println("您输入的id不存在,请重新输入!");
            }
        }
        return id;
    }
  • 把addStudent()和updateStudent()中录入学生信息的代码抽取到一个方法(inputStudentinfo)中
    • 该方法的主要作用就是录入学生的信息,并封装为学生对象,方法的返回值为Student类型
//录入学生的信息的方法inputStudentinfo(),并封装为学生对象并且返回
    private Student inputStudentinfo(String id) {
        //要先录入新的学生信息,并封装成学生对象(便于传输操作,一个一个信息修改的话比较麻烦也繁琐)
        //返回学生对象
        System.out.println("输入学生的姓名:");
        String name = sc.next();
        System.out.println("输入学生的年龄:");
        String age = sc.next();
        System.out.println("输入学生的生日:");
        String birthday = sc.next();

        Student student=new Student(id,name,age,birthday);

        return student;
    }

五、老师管理系统

  与学生管理系统同理,可以自己手动实现一下,更能初步的感受三层架构的简单用法,构建自己的分包分层思想

总结

   对JAVASE的学习有更新的认识,初步了解了三层架构和面向对象的思想,后期依据面向对象的三大特征会对该系统进行改进。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值