Java-开发团队调度软件

一、基本介绍

该项目是尚硅谷中JavaSE项目三,涉及内容有继承、异常、多态、接口等知识。

1、主界面

在这里插入图片描述
主界面如上图所示,主要关注点:职位、状态、奖金、股票、领用设备。

2、团队列表

在这里插入图片描述
团队成员现在包含ID是2的职员,具体显示属性和主界面也有所不同。

3、代码模块

在这里插入图片描述
domain中定义的职员和设备信息,其中Employee是Programmer的父类,Programmer是Designer的父类,Designer是Architect的父类,依次继承;Equipment是接口类,NoteBook、PC、Printer是实现接口的类。
junit包含单元测试类,可以不关注。
service中定义的有数据,相应的处理逻辑和异常处理。
view中定义的有与用户交互的界面功能,提供输入的功能函数TSUtility。

二、具体分析

集中介绍其中几个重要的类和方法。

1、Programmer类

public class Programmer extends Employee{

    private int memberId; // 在开发团队中的id

    // FREE,BUSY,VOCATION三种状态,表示程序员现在的状态
    // 默认是FREE状态。
    private Status status = Status.FREE;

    // equipment表示设备
    private Equipment equipment;

    public Programmer() {
        super();
    }

    public Programmer(int id, String name, int age, double salary, Equipment equipment) {
        super(id, name, age, salary);
        this.equipment = equipment;
    }

    public int getMemberId() {
        return memberId;
    }

    public void setMemberId(int memberId) {
        this.memberId = memberId;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public Equipment getEquipment() {
        return equipment;
    }

    public void setEquipment(Equipment equipment) {
        this.equipment = equipment;
    }

    public String toString(){
        return getDetails() + "\t程序员\t" + status + "\t\t\t\t\t" + 
        	   equipment.getDescription();
    }

    public String getDetailsForTeam(){
        return memberId + "/" + getId() + "\t\t" + getName() + "\t" + getAge() + "\t\t" +
               getSalary() + "\t" + "程序员";
    }
}

Programmer继承Employee类,特有属性memberId,该属性作为团队信息的关键字和Id一样是唯一的,status具有三种状态,FREE、BUSY、VOCATION。
toString方法进行重写,是为了在主菜单输出职员信息时可以统一,toString内的getDetails是在Employee中定义的,也是输出它的基本属性。
getDetailsForTeam是针对开发团队信息输出格式。

2、NoteBook类

public class NoteBook implements Equipment{
    private String model;
    private double price;  // 价格

    public NoteBook() {
    }

    public NoteBook(String model, double price) {
        this.model = model;
        this.price = price;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String getDescription() {
        return model + "(" + price + ")";
    }
}

NoteBook实现Equipment接口,Equipment接口中只有getDescription方法。

3、Data类

public class Data {

    // 10,11,12,13表示程序员的类型
    public static final int EMPLOYEE = 10;
    public static final int PROGRAMMER = 11;
    public static final int DESIGNER = 12;
    public static final int ARCHITECT = 13;

    // 21,22,23代表配备的电脑型号
    public static final int PC = 21;
    public static final int NOTEBOOK = 22;
    public static final int PRINTER = 23;


    // EMPLOYEE:    10,ID,NAME,AGE,SALARY
    // PRIGRAMMER:  11,ID,NAME,AGE,SALARY
    // DESIGNER:    12,ID,NAME,AGE,SALARY,BONUS
    // ARCHITECT:   13,ID,NAME,AGE,SALARY,BONUS,STOCK

    // 上面4个也是依次往下继承
    // EMPLOYEES存储职员信息,不同类型职员它的属性不同,例如,架构师有薪水、奖金和股票。
    public static final String[][] EMPLOYEES = {
            {"10", "1", "马云 ", "22", "20000"},
            {"13", "2", "马化腾", "23", "20000", "10000", "10000"},
            {"11", "3", "李彦宏", "24", "20000"},
            {"11", "4", "刘强东", "25", "20000"},
            {"12", "5", "雷军 ", "26", "20000", "10000"},
            {"11", "6", "任志强", "27", "20000"},
            {"12", "7", "柳传志", "28", "20000", "10000"},
            {"13", "8", "杨云庆", "29", "20000", "10002", "20000"},
            {"12", "9", "史玉柱", "22", "20000", "20000"},
            {"11", "10", "丁磊 ", "22", "20000"},
            {"11", "11", "张朝阳", "25", "8000"},
            {"12", "12", "杨致远", "27", "10000", "20000"}
    };

    // EQUIPMENTS是职员对应相应的设备。
    public static final String[][] EQUIPMENTS = {
            {},
            {"22", "联想T4", "6000"},
            {"21", "戴尔", "NEC17寸"},
            {"21", "戴尔", "三星17寸"},
            {"23", "佳能2900", "激光"},
            {"21", "华硕", "三星17寸"},
            {"21", "华硕", "三星17寸"},
            {"23", "爱普尔20K", "针式"},
            {"22", "惠普m6", "5800"},
            {"21", "戴尔", "NEC17寸"},
            {"21", "华硕", "三星17寸"},
            {"22", "惠普m6", "5800"}
    };

}

没有用到数据库,暂时在类中创建这些数据,EQUIPMENTS是对应员工的设备类型。

4、NameListService类

public class NameListService {
    private Employee[] employees;

    public NameListService(){
        // 根据Data类构建相应大小的employees数组
        // 再根据Data类中的数据构建不同的对象,包括Employee、Programmer、Designer
        // Architect
        // 根据EMPLOYEES来建立空间
        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]);
            // 在这里进行声明,避免后续重复进行声明。
            Equipment equipment;
            double bonus;
            int stock;
            switch (type){
                case EMPLOYEE:
                    employees[i] = new Employee(id, name, age, salary);
                    break;
                case PROGRAMMER:
                    // 找第i个职员的设备信息
                    equipment = creatEquipment(i);
                    employees[i] = new Programmer(id, name, age, salary, equipment);
                    break;
                case DESIGNER:
                    // 找第i个职员的设备信息
                    equipment = creatEquipment(i);
                    bonus = Double.parseDouble(EMPLOYEES[i][5]);
                    employees[i] = new Designer(id, name, age, salary, equipment, bonus);
                    break;
                case ARCHITECT:
                    equipment = creatEquipment(i);
                    bonus = Double.parseDouble(EMPLOYEES[i][5]);
                    stock = Integer.parseInt(EMPLOYEES[i][6]);
                    employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock);
                    break;
                default:
                    break;
            }
        }
    }

    // 获取指定位置员工的设备。
    public Equipment creatEquipment(int index){
        int type = Integer.parseInt(EQUIPMENTS[index][0]);

        switch (type){
            case PC: // 21
                return new PC(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
            case NOTEBOOK:
                return new NoteBook(EQUIPMENTS[index][1], Double.parseDouble(EQUIPMENTS[index][2]));
            case PRINTER:
                return new Printer(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
            default:
                break;
        }
        return null;
    }

    // 获取所有Employee
    public Employee[] getAllEmployees(){
        return employees;
    }

    // 获取某个id的职员
    // 有可能id找不到,抛出异常
    public Employee getEmployee(int id) throws TeamException{
        for (Employee employee : employees) {
            if (employee.getId() == id) {
                return employee;
            }
        }
        // 抛出异常
        throw new TeamException("找不到指定的职员");
    }
}

构造函数中将Data类中的数据,存储在Employee数组中,根据职员职位不同,new里面的信息也不相同。设备信息的创建也是根据型号的不同new不同实现Equipment接口的子类进行返回。
getAllEmployees方法是返回创建的职员信息。
getEmployee方法根据职员id好来查找相应的员工信息,如果找不到throw一个异常对象,然后用throws进行异常处理。

5、TeamService类

public class TeamService {

    private static int counter = 1;  // 给memberid赋值

    private static final int MAX_MEMBER = 5; // 限制开发团队的人数

    // 开发团队都必须是程序员以上的级别。
    private Programmer[] team = new Programmer[MAX_MEMBER]; // 保存开发成员

    private int total; // 记录开发团队的实际人数


    public TeamService() {
    }

    // 获取开发团队中的所有成员
    public Programmer[] getTeam(){
        Programmer[] team = new Programmer[total];
        for(int i = 0; i < team.length; ++i){
            team[i] = this.team[i];
        }
        return team;
    }

    // 将指定的员工添加到团队中
    /*
        限制条件:
        1、成员已满,无法添加
        2、该成员不是开发人员,无法添加
        3、该成员已在本开发团队中
        4、该成员已是某团队成员
        5、团队中至多只能有一名架构师
        6、团队中至多只能有两名设计师
        7、团队中至多只能有三名程序员
     */
    public void addMember(Employee e) throws TeamException{
        if(total >= MAX_MEMBER){
            throw new TeamException("成员已满,无法添加");
        }
        // 该成员不是程序员
        if(!(e instanceof Programmer)){
            throw new TeamException("该成员不是开发人员,无法添加");
        }
        // e肯定是一个programmer,所以它也可以调用方法getId或者getMemberId来进行比较。
        if(isExist(e)){
            throw new TeamException("该成员已在本开发团队中");
        }
        // 判断状态
        Programmer programmer = (Programmer) e;
        if("BUSY".equals(programmer.getStatus().getNAME())){
            throw new TeamException("该成员已是某团队成员");
        }else if("VOCATION".equals(programmer.getStatus().getNAME())){
            throw new TeamException("该成员正在休假,无法添加");
        }

        // 先看团队里几个架构师、设计师、程序员
        int numOfArch = 0, numOfDes = 0, numOfPro = 0;
        for(int i = 0; i < total; ++i){
            if(team[i] instanceof Architect){
                numOfArch++;
            }else if(team[i] instanceof Designer){
                numOfDes++;
            }else if(team[i] != null) numOfPro++;
        }
        if(programmer instanceof Architect){
            if(numOfArch >= 1) throw new TeamException("团队中至多只能有一名架构师");
        }else if(programmer instanceof Designer){
            if(numOfDes >= 2) throw new TeamException("团队中至多只能有两名设计师");
        }else if(numOfPro >= 3) throw new TeamException("团队中至多只能有三名程序员");

        programmer.setStatus(Status.BUSY);
        programmer.setMemberId(counter++);
        // 前面这两句放后面也行,因为指向是一样的。
        team[total++] = programmer;
    }

    private boolean isExist(Employee e){
        for(int i = 0; i < total; ++i){
            if(team[i].getId() == e.getId()){
                return true;
            }
        }
        return false;
    }

    // 从团队中删除成员
    public void removeMember(int memberId) throws TeamException{
        int i;
        for(i = 0; i < total; ++i){
            if(team[i].getMemberId() == memberId){
                team[i].setStatus(Status.FREE);
                break;
            }
        }
        if(i == total) throw new TeamException("找不到指定memberId的职员,删除失败");
        // 删除元素,覆盖前一个元素
        for(int j = i + 1; j < total; ++j){
            team[j - 1] = team[j];
        }
        team[--total] = null;
    }
}

首先明确其实对团队成员信息的增加、删除、显示。
getTeam方法获取当前在团队中的员工信息。
addMember方法将员工信息加入,有很多种限制条件需要去考虑,例如员工职位必须是Programmer以上才行,而且最后如果成功将员工信息加入团队中,需要将其状态设置为BUSY。
removeMember方法按照memberId查找团队中成员信息,如果查找到了,将其状态设置为FREE,而且将其后面的元素往前移动一位,最后一个数组元素设置为null;如果查找不到,那么则throw一个异常信息。

6、TeamException类

public class TeamException extends Exception{
    // 提供uid
    static final long serialVersionUID = -3282772728L;

    public TeamException(){

    }

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

}

自定义类,将throw过来的msg传给父类,然后在具体的方法通过进行try-catch,可以用getMessage来打印相应的失败原因信息。

7、TeamView类

public class TeamView {
    private NameListService listService = new NameListService();
    private TeamService teamService = new TeamService();

    public void enterMainMenu(){
        boolean loopflag = true;
        char menu;
        listAllEmployees();
        while(loopflag){
            System.out.println("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出");
            System.out.print("请选择(1-4)");
            menu = TSUtility.readMenuSelection();
            if(menu != '1' && menu != '4')
                listAllEmployees();
            switch (menu){
                case '1':
                    getTeam();
                    break;
                case '2':
                    getTeam();
                    addMember();
                    break;
                case '3':
                    getTeam();
                    deleteMember();
                    break;
                case '4':
                    System.out.print("是否要退出(Y/N):");
                    char isExit = TSUtility.readConfirmSelection();
                    if(isExit == 'Y')
                        loopflag = false;
                    break;
            }
        }

    }

    // 显示所有的员工信息
    private void listAllEmployees(){
        System.out.println("------------------------开发团队调度软件---------------------------");
        Employee[] employees = listService.getAllEmployees();
        if(employees == null || employees.length == 0){
            System.out.println("该公司中没有任何员工信息");
        }else{
            System.out.println("ID\t姓名\t\t年龄\t工资\t\t职位\t\t状态\t\t奖金\t\t股票\t\t领用设备");
            for(Employee employee: employees){
                System.out.println(employee);
            }
        }
        System.out.println("-----------------------------------------------------------------");
    }

    private void getTeam(){
        System.out.println("------------------------团队成员列表---------------------------");
        Programmer[] team = teamService.getTeam();
        if(team == null || team.length == 0){
            System.out.println("开发团队没有成员!");
        }else{
            System.out.println("TID/ID\t姓名\t\t年龄\t\t工资\t\t职位\t\t奖金\t\t股票");
            for(int i = 0; i < team.length; ++i){
                // 不能直接使用toString
                // 需要重写
                System.out.println(team[i].getDetailsForTeam());
            }
        }
        System.out.println("-------------------------------------------------------------");
    }

    private void addMember(){
        System.out.println("------------------------添加成员---------------------------");
        System.out.print("请输入要添加的员工ID:");
        int id = TSUtility.readInt();
        try{
            Employee employee = listService.getEmployee(id);
            teamService.addMember(employee);
            System.out.println("添加成功!");
        }catch (TeamException e){
            System.out.println("添加失败" + e.getMessage());
        }
    }

    private void deleteMember(){
        System.out.println("------------------------删除成员---------------------------");
        System.out.print("请输入要删除的员工TID:");
        int memberId = TSUtility.readInt();
        System.out.print("确认是否删除(Y/N):");
        char isDelete = TSUtility.readConfirmSelection();
        if(isDelete == 'Y'){
            try{
                teamService.removeMember(memberId);
                System.out.println("删除成功!");
            }catch (TeamException e){
                System.out.println("删除失败!原因是:" + e.getMessage());
            }
        }
    }

    public static void main(String[] args) {
        TeamView teamView = new TeamView();
        teamView.enterMainMenu();
    }
}

listAllEmployees方法显示员工信息。
getTeam方法显示团队成员信息。

3、总结

通过TeamView进行交互,NameListService是对于员工信息的操作,TeamService是对团队成员的操作,domain中的类就是一些基本的职员信息类和设备信息类,采用继承、实现接口。将一些暂时不处理的异常抛出,用throws异常处理方式,然后调用相应方法时再用catch进行处理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JHL123123

赞赏随心,支持为大。

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

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

打赏作者

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

抵扣说明:

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

余额充值