Java-----基于面向对象开发学生管理系统

2021-12-15  本文已影响0人  会写代码的小猿猴

1、大致功能

开发一个简单的系统,该系统可以对学生进行增删改查(CRUD);

2、需求分析

3、基本类的创建

在开发中,我们要学会对很多类进行分类思想,不能把所有的类一股脑塞到一个包里面,下面是我对这个小demo类的分类分包的详情。


image.png

搭建以后目录结构如下所示:


image.png

4、菜单搭建

主要分为主菜单搭建和学生管理系统菜单搭建
先来看主菜单搭建,主菜搭建在程序入口InfoManagerEntry里面进行搭建
主菜单搭建:

public class InfoManagerEntry {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        //主菜单搭建
        while(true){
            System.out.println("----------欢迎来到学生老师管理系统----------");
            System.out.println("请输入您的选择:1、学生管理  2、老师管理  3、退出");
            String choice = sc.next();
            switch(choice){
                case "1":
                    //开启学生管理系统
                    StudentController studentcontroller=new StudentController();
                    studentcontroller.start();
                    break;
                case "2":
                    System.out.println("老师管理");
                    break;
                case "3":
                    System.out.println("感谢您的使用");
                    //退出当前正在运行的JVM虚拟机,关闭程序
                    System.exit(0);
                    break;
                default:
                    System.out.println("您的输入有误,清重新输入");
                    break;
            }
        }

    }
}

上面代码中我们输入1进入学生管理系统,执行StudentController 的Start()方法,StudentController 代码实现如下:

public class StudentController {
    //该方法用于开启学生管理系统,展示学生管理系统菜单
    public void start() {
        Scanner sc=new Scanner(System.in);
        studentLoop:while(true){
            System.out.println("----------欢迎来到学生管理系统----------");
            System.out.println("请输入您的选择:1、添加学生  2、删除学生  3、修改学生  4、查找学生  5、退出");
            String choice = sc.next();
            switch(choice){
                case "1":
                    System.out.println("添加");
                    break;
                case "2":
                    System.out.println("删除");
                    break;
                case "3":
                    System.out.println("修改");
                    break;
                case "4":
                    System.out.println("查找");
                    break;
                case "5":
                   /* 这里是退出这个循环而不是退出JVM虚拟机,所以不能用System.exit(),
                    这里的做法是给循环取个名字叫studentLoop,然后输入5后break这个循环就可以了*/
                    System.out.println("感谢您使用学生管理系统,再见!");
                    break studentLoop;
                default:
                    System.out.println("您的输入有误,清重新输入");
                    break;
            }
        }

    }
}

到这里基本的菜单搭建就完成了,接下来我们把菜单里面的功能一个个实现出来。

5、添加功能的实现

添加功能分析(主要着重分包分类思想分析,每个类的分工合作)


image.png

这里需要明确不同包下的每个类的作用,我在第三步中已经给出了每个类具体负责的事务。大家自己领悟就好。
代码实现,如上图所示,在上图三个类中都有一个addStudent()方法,每个方法需要实现不同的功能,我们先来看StudentController里面的addStudent方法,图中说明该方法主要实现以下功能:

 public void addStudent() {
        //1、接收用户输入的信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生id:");
        String id = sc.next();
        System.out.println("请输入学生姓名:");
        String name = sc.next();
        System.out.println("请输入学生年龄:");
        String age = sc.next();
        System.out.println("请输入学生生日:");
        String birthday = sc.next();
        //2、将学生信息封装为学生对象传递给StudentService
        Student stu = new Student(id, name, age, birthday);
        //3、将学生对象传递给StudentService中的addStudent方法
        StudentService studentservice = new StudentService();
        boolean result = studentservice.addStudent(stu);
        //4、接收方法的boolean类型返回值,根据结果在控制台打印添加成功\添加失败
        if (result) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }

    }

然后在用户输入1时调用就可以了,

  case "1":
                    addStudent();
                    break;

在上面这个方法中需要接收StudentService 中的addStudent方法返回的结果,再来看看StudentService 中的addStudent方法,上面图中已经给出这个方法需要实现的功能,直接照着写就好了。

//1.将接受到的学生对象,传递给StudentDao
//2.接受方法的boolean返回值将结果返还给StudentC ontroller
 public boolean addStudent(Student stu) {
        StudentDao studentdao = new StudentDao();
        return studentdao.addStudent(stu);
    }

这个方法又用到了StudentDao 里面的addStudent方法,也是一样的,根据需求在studentdao内部实现该方法就可以了。代码如下:

public boolean addStudent(Student stu) {
        //1.创建Student学生数组长度为5
        Student[] students = new Student[5];
        // 2.将接受到的学生对象添加到数组中
        int index = -1;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student == null) {
                index = i;
                break;
            }
        }
        //3.返回是否添加成功的boolean类型值
        if (index == -1) {
            return false;
        } else {
            students[index] = stu;
            return true;
        }
    }

但是上面的代码还有缺陷,比如我们输入一个已经存在的学生,他也会直接添加进去,所以我们需要添加判断学生是否存在的逻辑代码,这部分逻辑代码同样使用分包分类的思想,先来看一个分析图:


image.png

判断id是否存在属于业务逻辑代码,应该在StudentService中实现,接收学生id属于和用户打交道,在StudentController中实现,实现判断时需要拿到现在数组中的所有学生对象,这个属于访问存贮数据,应该在StudentDao中实现,这里我直接把每个类的完整代码贴出来了。
StudentController:

public class StudentController {
    //该方法用于开启学生管理系统,展示学生管理系统菜单
    public void start() {
        Scanner sc = new Scanner(System.in);
        studentLoop:
        while (true) {
            System.out.println("----------欢迎来到学生管理系统----------");
            System.out.println("请输入您的选择:1、添加学生  2、删除学生  3、修改学生  4、查找学生  5、退出");
            String choice = sc.next();
            switch (choice) {
                case "1":
                    addStudent();
                    break;
                case "2":
                    System.out.println("删除");
                    break;
                case "3":
                    System.out.println("修改");
                    break;
                case "4":
                    System.out.println("查找");
                    break;
                case "5":
                   /* 这里是退出这个循环而不是退出JVM虚拟机,所以不能用System.exit(),
                    这里的做法是给循环取个名字叫studentLoop,然后输入5后break这个循环就可以了*/
                    System.out.println("感谢您使用学生管理系统,再见!");
                    break studentLoop;
                default:
                    System.out.println("您的输入有误,清重新输入");
                    break;
            }
        }

    }


    public void addStudent() {
        //1、接收用户输入的信息
        StudentService studentservice = new StudentService();
        Scanner sc = new Scanner(System.in);
        String id;
        while (true) {
            System.out.println("请输入学生id:");
            id = sc.next();
            boolean flag = studentservice.isExits(id);
            if (flag) {
                System.out.println("学号已被占用,请重新输入");
            } else {
                break;
            }
        }
        System.out.println("请输入学生姓名:");
        String name = sc.next();
        System.out.println("请输入学生年龄:");
        String age = sc.next();
        System.out.println("请输入学生生日:");
        String birthday = sc.next();
        //2、将学生信息封装为学生对象传递给StudentService
        Student stu = new Student(id, name, age, birthday);
        //3、将学生对象传递给StudentService中的addStudent方法

        boolean result = studentservice.addStudent(stu);
        //4、接收方法的boolean类型返回值,根据结果在控制台打印添加成功\添加失败
        if (result) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }

    }
}

StudentService:

public class StudentService {
    StudentDao studentdao = new StudentDao();
    public boolean addStudent(Student stu) {
        return studentdao.addStudent(stu);
    }

    public boolean isExits(String id) {
        Student[] stus = studentdao.findAllAtudents();
        boolean exits = false;
        for (int i = 0; i < stus.length; i++) {
            Student student = stus[i];
            if (student != null && student.getId().equals(id)) {
                exits = true;
                break;
            }
        }
        return exits;
    }
}

StudentDao:

public class StudentDao {
    //1.创建Student学生数组长度为5
    Student[] students = new Student[5];
    public boolean addStudent(Student stu) {
        // 2.将接受到的学生对象添加到数组中
        int index = -1;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student == null) {
                index = i;
                break;
            }
        }
        //3.返回是否添加成功的boolean类型值
        if (index == -1) {
            return false;
        } else {
            students[index] = stu;
            return true;
        }
    }

    public Student[] findAllAtudents() {
        return students;
    }
}

然后我在测试的时候发现我先添加一个学生,然后在添加同样的学生还是能添加进去,这是为什么呢,其实原因就是因为第二次添加的时候它会重新创建一个对象,和第一次添加的对象不是同一个导致他不能判断是否重复,怎么解决呢?这里就要用到Static关键字了,下面是static关键字的一些知识点。


image.png

在内存中有一块静态存储位置专门负责存储status修饰的内容,随着类的加载它会一直存在。
使用Static需要注意的几点:

public class StudentDao {
    //1.创建Student学生数组长度为5
    public static Student[] students = new Student[5];
    public boolean addStudent(Student stu) {
        // 2.将接受到的学生对象添加到数组中
        int index = -1;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student == null) {
                index = i;
                break;
            }
        }
        //3.返回是否添加成功的boolean类型值
        if (index == -1) {
            return false;
        } else {
            students[index] = stu;
            return true;
        }
    }

    public Student[] findAllAtudents() {
        return students;
    }
}

学号重复问题测试效果如下:


image.png

到这里整个添加方法就实现了,这样层层嵌套就是为了说明一个分包分类思想,哪些功能需要由哪个类来实现,放在哪个包下,在实际开发中也是需要这样来降低程序的耦合度,这样便于维护代码,要是全部揉成一坨后期维护会非常非常困难,这一点博主也是深有体会。

6、查看学生代码实现

同样的先来分析每个类需要完成的工作:


image.png

这个很简单了,参照开头给出的分类分包思想图进行分析就可以了。
代码实现(根据上图步骤创建每个类中的方法)
StudentController中的findAllStudent方法:

   private void findAllAtudents() {
        Student[] stus=studentservice.findAllStudents();
        if (stus==null){
            System.out.println("系统内暂无学生信息,请添加重试");
            return;
        }else{
            for (int i = 0; i < stus.length; i++) {
                Student stu3=stus[i];
                if (stu3!=null) {
                    System.out.println("学号:" + stus[i].getId() + "姓名:" + stus[i].getName() + "年龄:" + stus[i].getAge() + "生日:" + stus[i].getBirthday());
                }
            }
        }
    }

StudentService中的findAllStudent方法:

  public Student[] findAllStudents() {
        Student[] stus = studentdao.findAllAtudents();
        boolean flag = false;
        for (int i = 0; i < stus.length; i++) {
            Student stus1 = stus[i];
            if (stus1 != null) {
                flag = true;
            }
        }
        if (flag) {
            return stus;
        } else {
            return null;
        }
    }

StudentDao中的findAllStudents方法:

public Student[] findAllAtudents() {
        return students;
    }

测试结果:


image.png

7、删除学生代码实现

和前面一样,先来一张思路分析图:


image.png

StudentController中的deleteStudentById方法:

  public void deleteStudentById(){
        System.out.println("请输入需要删除的学生id");
        Scanner sc=new Scanner(System.in);
        String id=sc.next();
        boolean exits = studentservice.isExits(id);
        if (exits){
            boolean b = studentservice.deleteStudentById(id);
            if (b){
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        }else{
            System.out.println("没有该名学生,不需要删除");
        }
    }

StudentService中的deleteStudentById方法:

 public boolean deleteStudentById(String id) {
        boolean isDelete=studentdao.deleteStudentById(id);
        return isDelete;
    }

StudentDao中的deleteStudentById方法:

public boolean deleteStudentById(String id) {
        boolean b = false;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student.getId().equals(id)) {
                students[i] = null;
                b = true;
                break;
            }
        }
        return b;
    }

测试效果:


image.png

8、修改学生代码实现

这里我就不一一去分析了,大家可以参照前面的三个对它每个类里面的修改方法做功能分析,我在这里就直接上代码了。
StudentController中的updateStudentById方法:

public void updateStudentById() {
        Scanner sc1 = new Scanner(System.in);
        String id;

        System.out.println("请输入需要修改的学生id:");
        id = sc1.next();
        boolean flag = studentservice.isExits(id);
        if (!flag) {
            System.out.println("未找到该名学生!");
            return;
        }
        System.out.println("请输入学生姓名:");
        String name = sc1.next();
        System.out.println("请输入学生年龄:");
        String age = sc1.next();
        System.out.println("请输入学生生日:");
        String birthday = sc1.next();
        //2、将学生信息封装为学生对象传递给StudentService
        Student stu = new Student(id, name, age, birthday);
        //3、将学生对象传递给StudentService中的addStudent方法

        boolean result = studentservice.updateStudentById(stu,id);
        //4、接收方法的boolean类型返回值,根据结果在控制台打印添加成功\添加失败
        if (result) {
            System.out.println("修改成功");
        } else {
            System.out.println("修改失败");
        }
    }

StudentService中的updateStudentById方法:

public boolean updateStudentById(Student stu, String id) {
        return studentdao.updateStudentById(stu,id);
    }

StudentDao中的updateStudentById方法:

public boolean updateStudentById(Student stu, String id) {
        boolean b1 = false;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student.getId().equals(id)) {
                students[i] = stu;
                b1 = true;
                break;
            }
        }
        return b1;
    }

最后上一个测试截图:


image.png

总结:其实开发这样一个简单的学生管理系统非常简单,甚至可能觉得我把这个过程弄得非常复杂,很多人会觉得没必要这样,我想说的是,这么简单的系统很多人都能做,我只是想通过这个简单的demo来温习一下Java中的分类分包思想,什么包下的类需要做什么事,每个包下面的类分工合作完成整个工程,这才是我想要传达给大家的,这在开发中对降低代码耦合度有很好的作用,我们在开发中也应该时刻把这种原则放在第一位,否则写出来的代码会变得杂乱无章,甚至自己维护都非常费力,更别提代码迭代了。
就这样吧,有问题请评论去留言,会第一时间改正。。

上一篇 下一篇

猜你喜欢

热点阅读