基于Java基础的开发团队调度软件

前言


提前祝大家中秋快乐了呀,时隔多日,我终于开始了 Java 基础 的第三个练手案例。至于为什么这么久才对这个练手案例动刀,说多了都是泪,这段时间新生开学,狗子我还调了宿舍,在搬宿舍的同时,一度被穿着蓝色军训服的大一新生围城 (# ̄~ ̄#)师兄师姐你们怎么不吃饭

好了不瞎扯了,后续也要加大力度了,否则被大一的师弟师妹们卷下去就很丢脸。

这次的是基于 Java基础 的第三个练手案例,和前两个一样,依旧是来自于 尚硅谷 的案例,真香 ~ 。在下文中将会对其基于我自己的理解,结合尚硅谷那边的解说逐一介绍案例中的过程和细节,文章可能会有点长部分源码就不放出来了。前两个案例的文章有兴趣的小伙伴可以自行跳转去查看呀!

噢对了,从这边文章开始狗子我的昵称便更改了,并且以后都是这个昵称。至于为什么呢?嗯嗯嗯……毕竟女朋友喜欢这个外号,<( ̄︶ ̄)>。开干!

一、前期准备


在开始搞事情之前得先准备好下面这些东西,其中 JDK 和 IDE 不一定需要统一,这只是狗子我使用的版本而已。准备好之后带上我们的脑子就可以开搞啦

  • 编程语言 : Java
  • 运行环境 : JDK1.8
  • IDE : IDEA 2020
  • 储备知识 : Java基础

二、整体架构介绍


在这次案例中和第二次案例一样,同样使用到了 MVC框架 ,将业务层和视图层进行分离,提高了程序的可维护性,降低了耦合性,这一框架模式也是从尚硅谷的教学中学习得来,‘真’ YYDS。在下面中分别对 尚硅谷 和 狗子我个人 的结构图进行展示,我的是基于尚硅谷的进行绘画的,主要是为了更好理解

  1. 尚硅谷
    在这里插入图片描述

  2. 狗子本狗
    DTS

三、工具类


在尚硅谷的文件中提供了已经封装好的 TSUtility 工具类,方便我们实现键盘的访问。由于工具类中涉及到的都已经接触过,因此这个工具类便自己进行了编写,如果是从视频那边过来的话也可以直接跳过工具类的编写,不过还是推荐自己尝试一下。

函数名功能介绍返回类型
readMenuSelection用于界面菜单的选择int
readInt从键盘中读取一个不超过二位数的整数int
readConfirmSelection用于确认选择的输入,读取‘Y’或‘N’char
readKeyBoard用于记录用户从键盘中输入的数据String
readReturn提示并等待,直到用户按回车键后返回。void

同样在这里附上一小撮截图
演示截图

四、功能浅谈

1、 domain


这个模块是 MVC设计模式 里面的 M(model), 在这里封装了众多 JavaBean类,如员工职位和设备种类等
domain

1.1、 员工类

  1. Employee类

    这是封装了普通员工信息的类,同时也是其余员工的直接或间接父类,其封装内容如下,分别为员工工号、员工姓名、员工年龄以及员工薪资,提供对应的构造器并在本类中重写了 toString() 方法来展示员工信息。
    Employee

  2. Programmer类

    在本类中封装了程序员的信息,这也是加入团队的最低要求。这继承了 Employee 类,同时也是后面 Architect 类Designer 类的父类。除了继承了父类的属性之外,还封装了团队编号、状态情况以及设备情况,同时提供对应的构造器并在本类中重写了 toString() 方法来展示员工信息。
    在这里插入图片描述

  3. Designer类

    在本类中封装了设计师的信息,这继承了 Programmer 类,同时也是后面 Architect 类的父类。除了继承了父类的属性之外,还封装了团队编号、状态情况以及设备情况,同时提供对应的构造器并在本类中重写了 toString() 方法来展示员工信息。
    在这里插入图片描述

  4. Architect类
    在本类中封装了架构师的信息,这继承了 Designer 类。除了继承了父类的属性之外,还封装了股票数量属性,同时提供对应的构造器并在本类中重写了 toString() 方法来展示员工信息。
    在这里插入图片描述

1.2、 设备接口

由于在后续的操作中每个成员的设备并不明确,因此在这里定义一个设备接口,后方使用多态性从而减少代码的冗余。在其下面,PC类NoteBook类Printer类 都分别实现了这一接口并提供了对应的属性和方法(下方放的图是尚硅谷作图的,直接扒过来了)
在这里插入图片描述

2、 service

该模块是 MVC模式 中的 C(control),为实体对象(Employee及其子类如程序员等)的管理模块


2.1、 Data 类

这个是采用了尚硅谷的数据类,这里面记录了公司内所有的员工信息

public class Data {
    public static final int EMPLOYEE = 10;      //普通职工
    public static final int PROGRAMMER = 11;    //程序员
    public static final int DESIGNER = 12;      //设计师
    public static final int ARCHITECT = 13;     //架构师

    public static final int PC = 21;            //电脑
    public static final int NOTEBOOK = 22;      //笔记本
    public static final int PRINTER = 23;       //打印机

    //Employee  :  10, id, name, age, salary
    //Programmer:  11, id, name, age, salary
    //Designer  :  12, id, name, age, salary, bonus
    //Architect :  13, id, name, age, salary, bonus, stock
    public static final String[][] EMPLOYEES = {
            {"10", "1", "马  云", "22", "3000"},
            {"13", "2", "马化腾", "32", "18000", "15000", "2000"},
            {"11", "3", "李彦宏", "23", "7000"},
            {"11", "4", "刘强东", "24", "7300"},
            {"12", "5", "雷  军", "28", "10000", "5000"},
            {"11", "6", "任志强", "22", "6800"},
            {"12", "7", "柳传志", "29", "10800", "5200"},
            {"13", "8", "杨元庆", "30", "19800", "15000", "2500"},
            {"12", "9", "史玉柱", "26", "9800", "5500"},
            {"11", "10", "丁  磊", "21", "6600"},
            {"11", "11", "张朝阳", "25", "7100"},
            {"12", "12", "杨致远", "27", "9600", "4800"}
    };

    //如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应
    //PC      :21, model, display
    //NoteBook:22, model, price
    //Printer :23, name, type 
    public static final String[][] EQUIPMENTS = {
            {},
            {"22", "联想T4", "6000"},
            {"21", "戴尔", "NEC17寸"},
            {"21", "戴尔", "三星 17寸"},
            {"23", "佳能 2900", "激光"},
            {"21", "华硕", "三星 17寸"},
            {"21", "华硕", "三星 17寸"},
            {"23", "爱普生20K", "针式"},
            {"22", "惠普m6", "5800"},
            {"21", "戴尔", "NEC 17寸"},
            {"21", "华硕", "三星 17寸"},
            {"22", "惠普m6", "5800"}
    };
}

2.2、 Status类

这是记录员工状态的类,将构造器私有化,只在类中声明三个对象属性,分别表示成员的空闲、繁忙和休假的状态。

public class Status {
    private final String STATUS;      //记录用户状态

    private Status(String STATUS) {
        this.STATUS = STATUS;
    }
    public static final Status FREE = new Status("FREE");
    public static final Status BUSY = new Status("BUSY");
    public static final Status VOCATION = new Status("VOCATION");

    public String getSTATUS() {
        return STATUS;
    }

    @Override
    public String toString() {
        return STATUS;
    }
}

2.3、 TeamException 类

在本类中自定义了在团队操作过程中的操作异常

public class TeamException extends Exception {
    static final long serialVersionUID = -7034897115645766939L;

    public TeamException() {

    }

    public TeamException(String message) {
        super(message);
    }
}

2.4、 NameService 类

该类负责将 Data类 中的数据封装到 Employee[] 数组中,同时提供相关操作 Employee[] 的方法。
在这里插入图片描述

  1. 值得注意的是该类中的构造器的编写:
  • 根据项目提供的Data类构建相应大小的 employees 数组
  • 再根据 Data类 中的数据构建不同的对象,包括 EmployeeProgrammerDesignerArchitect 对象,以及相关联的 Equipment 子类的对象
  • 将对象存于数组中
    public NameListService() {
        employees = new Employee[EMPLOYEES.length]; //开辟公司员工个数大小的空间
    
        //通过循环逐个创建不同工种的员工对象
        for (int i = 0; i < EMPLOYEES.length; i++) {
    
            //获取每一个职位都有的属性
            int type = Integer.parseInt(EMPLOYEES[i][0]);   //工种
            int id = Integer.parseInt(EMPLOYEES[i][1]);     //工号
            String name = EMPLOYEES[i][2];                  //姓名
            int age = Integer.parseInt(EMPLOYEES[i][3]);    //年龄
            double salary = Double.parseDouble(EMPLOYEES[i][4]);    //工资
    
            //特殊工种特定的属性获取
            int stock;              //声明股票数量
            double bonus;           //声明奖金
            Equipment equipment;    //声明设备变量
    
            //通过不同的工种实例化不同的对象
            switch(type) {
                case EMPLOYEE: {
                    employees[i] = new Employee(id, name, age, salary);
                    break;
                }
                case PROGRAMMER: {
                    equipment = creatEquipment(i);  //programmer 的设备
                    employees[i] = new Programmer(id, name, age, salary, equipment);
                    break;
                }
                case DESIGNER: {
                    bonus = Double.parseDouble(EMPLOYEES[i][5]);    //designer 的奖金
                    equipment = creatEquipment(i);                  //designer 的设备
                    employees[i] = new Designer(id, name, age, salary, equipment, bonus);
                    break;
                }
                case ARCHITECT: {
                    bonus = Double.parseDouble(EMPLOYEES[i][5]);    //architect 的奖金
                    equipment = creatEquipment(i);                  //architect 的设备
                    stock = Integer.parseInt(EMPLOYEES[i][6]);      //architect 的股票数量
                    employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock);
                    break;
                }
            }
        }
    }
    
  1. 剩余方法介绍
方法名功能返回值
getAllEmployees()获取所有员工信息Employee[]
getEmployee通过 id 索引返回员工信息并有可能会抛出异常Employee
creatEquipment根据不同的设备号创建不同的设备对象Equipment

2.5、 TeamService 类

在这里封装了关于开发团队成员的管理方法,如添加、删除等,并封装了团队人数、架构师人数、设计师人数、程序员人数、团队最大容纳人数和用于自动生成团队成员编号的静态变量,同时提供了对应的 get() 方法
在这里插入图片描述
在这里对本类中的方法进行一个简单的介绍

  • getTeam() : 用于获取开发团队的所有成员信息。无参数列表,返回值为 Programmer[]
  • isExist() : 用于判断员工是否已经存在于团队。参数列表为需要判断的员工(Programmer p),返回值为 boolean
  • addMembe() : 用于添加团队成员,若该成员不存在,则抛出 TeamException 异常。参数列表为需要添加的员工(Employee e),无返回值;
  • removeMember() : 用于通过在团队中的团队 Id 删除团队成员,若该成员不存在,则抛出 TeamException 异常。参数列表为需要移除的成员的团队成员编号(int memberId),返回值为空;

3、 view


这个模块是 MVC设计模式 里面的 V(view), 该模块为主控模块,负责菜单的显示和处理用户操作,几乎所有的交互都将在这一模块中完成。在本模块中包含了两个类,分别是 TSUtility 工具类以及 TeamView 类,其中工具类上方已经介绍过了,下面就主要介绍另外一个类。

3.1、 TeamView

在本类中通过与用户的交互,逐一实现各个功能。
在这里插入图片描述
类内部封装的属性有 listServiceteamService 变量,都是供类中方法使用的,以及众多方法,通过 enterMainMenu() 方法在显示主菜单界面的同时,通过与用户的交互,从而进行调用其余方法。以下方法仅供 enterMainMenu() 方法调用:

  • listAllEmployees ():以表格形式列出公司所有成员
  • getTeam():显示团队成员列表操作
  • addMember ():实现添加成员操作
  • deleteMember ():实现删除成员操作
public void enterMainMenu() {
    boolean isLoop = true;
    int selection = 0;
//        TeamView menu = new TeamView();   //如果写成这样子的话就会出错,公司名单无法更新
    while(isLoop) {
        if(selection != 1) {
            listAllEmployees();         //错误:menu.listAllEmployees();
        }
        System.out.print("1-团队列表  2-添加团队成员  3-删除团队成员 4-退出   请选择(1-4):");
        selection = TSUtility.readMenuSelection();
        switch(selection) {
            case 1: {
                listTeam();     //团队列表
                break;
            }
            case 2: {
                addMember();    //添加成员
                break;
            }
            case 3: {
                deleteMember(); //删除成员
                break;
            }
            case 4: {
                System.out.print("确认是否退出(Y/N):");
                char confirm = TSUtility.readConfirmSelection();
                if(confirm == 'Y') {
                    isLoop = false;
                }
                break;
            }
        }
    }
}

这里需要注意的是在 enterMainMenu() 方法中注释的地方,狗子我找了半天之后终于找到了这个顽强的 bug((╬━㉨━)凸) ,初步怀疑是因为内存空间分配的原因,但不确定,因此去请教了我的老师。

  • 老师给出的答案是在这里如果对该类进行实例化的话(TeamView menu = new TeamView()),就会在内存中生成另外一块空间,那么在调用下方的方法时,就会在这一块堆空间中进行操作,但是团队的对应操作是在本类中的空间进行操作的因为在主函数中进行了实例化 new TeamView().enterMainMenu()),两块空间由于没有任何联系,因此对团队操作并不会影响到我们申请的 menu 空间,在测试时便会出错,具体 bug 情况可以自己去生产看看效果((ʘ̆㉨ʘ̆)

五、收获

怎么说呢,这次做的案例收获还是蛮多的,毕竟是结合了前面所学的 Java基础 进行一个整体复习的案例,不像前面两个一样只是部分的。

  • 在这个案例中会发现到处都有多态的影子,这就让狗子我对多态性的理解更上一层楼,并且对其的运用也更加顺手
  • 第二次使用 MVC设计框架 还是有点不一样的,对它的使用方式还是熟悉了很多,对多文件的情况可以很大程度上增加自己开发时的逻辑性
  • 最大的收获还是上面提及到的那个 bug ,这让我体会到了痛苦并快乐着的感觉(((유㉨유|||)))解决了这个 bug 之后会发现,自己对实例化这一块的掌握更多了,相对于之前只会用的程度上,感觉得到了升华

六、总结

对于Java基础来说,这个案例是三个案例里面相对全面的,可以较好的梳理和加强对Java三大特性的理解和使用,对之前的那句话 “你不动手,永远停留在想象层面” 感受更深了,毕竟也被一个 bug 折磨了一段时间。

这次的源码已经整理好了,一直决定这里的资源分享好像不太好使,因此抽空去学了一下 gitee码云 的基本用法并整理了这三次的源码放在 gitee 仓库中(别问为什么不放在 github 上,问了就是进入网址得看命)
gitee仓库地址 – > https://gitee.com/Aqting/javacase.git

在这里插入图片描述

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈宝子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值