基于文本界面的《开发团队调度软件》
一、功能介绍
1.软件启动时,根据给定的数据创建公司部分成员列表(数组)
2.根据菜单提示,基于现有的公司成员,组建一个开发团队
3.组建过程包括将成员插入到团队中,或从团队中删除某成员,还可以列出团队中现有成员的列表
(1)添加团队成员
①当选择“添加团队成员”菜单时,将执行从列表中添加指定(通过ID)成员到开发团队的功能
②添加成功后,按回车键将重新显示主界面
③如果添加操作因某种原因失败,将显示信息
失败信息包含以下几种:
-
成员已满,无法添加
-
该成员不是开发人员,无法添加
-
该员工已在本开发团队中
-
该员工已是某团队成员
-
该员正在休假,无法添加
-
团队中至多只能有一名架构师
-
团队中至多只能有两名设计师
-
团队中至多只能有三名程序员
(2)删除团队成员
①当选择“删除团队成员”菜单时,将执行从开发团队中删除指定(通过TeamID)成员的功能
②删除成功后,按回车键将重新显示主界面
(3)团队列表:当选择“团队列表”菜单时,将列出开发团队中的现有成员
4.开发团队成员包括架构师、设计师和程序员
二、步骤
(1)按照设计要求,创建所有包
package com.project3.service;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, stockpublic 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)键盘访问的实现
package com.project3.view;import java.util.*;
/*** * @Description 项目中提供了TSUtility.java类,可用来方便地实现键盘访问。* @author shkstart Email:shkstart@126.com* @version * @date 2019年2月12日上午12:02:58**/
public class TSUtility {private static Scanner scanner = new Scanner(System.in);/*** * @Description 该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。* @author shkstart* @date 2019年2月12日上午12:03:30* @return*/public static char readMenuSelection() {char c;for (; ; ) {String str = readKeyBoard(1, false);c = str.charAt(0);if (c != '1' && c != '2' &&c != '3' && c != '4') {System.out.print("选择错误,请重新输入:");} else break;}return c;}/*** * @Description 该方法提示并等待,直到用户按回车键后返回。* @author shkstart* @date 2019年2月12日上午12:03:50*/public static void readReturn() {System.out.print("按回车键继续...");readKeyBoard(100, true);}/*** * @Description 该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。* @author shkstart* @date 2019年2月12日上午12:04:04* @return*/public static int readInt() {int n;for (; ; ) {String str = readKeyBoard(2, false);try {n = Integer.parseInt(str);break;} catch (NumberFormatException e) {System.out.print("数字输入错误,请重新输入:");}}return n;}/*** * @Description 从键盘读取‘Y’或’N’,并将其作为方法的返回值。* @author shkstart* @date 2019年2月12日上午12:04:45* @return*/public static char readConfirmSelection() {char c;for (; ; ) {String str = readKeyBoard(1, false).toUpperCase();c = str.charAt(0);if (c == 'Y' || c == 'N') {break;} else {System.out.print("选择错误,请重新输入:");}}return c;}private static String readKeyBoard(int limit, boolean blankReturn) {String line = "";while (scanner.hasNextLine()) {line = scanner.nextLine();if (line.length() == 0) {if (blankReturn) return line;else continue;}if (line.length() < 1 || line.length() > limit) {System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");continue;}break;}return line;}
}
(3)Equipment接口及其实现子类的设计
package com.project3.domain;public interface Equipment {public abstract String getDescription();
}
package com.project3.domain;public class PC implements Equipment{private String model;//机器的型号private String display;//显示器名称public PC() {super();}public PC(String model, String display) {super();this.model = model;this.display = display;}public String getModel() {return model;}public void setModel(String model) {this.model = model;}public String getDisplay() {return display;}public void setDisplay(String display) {this.display = display;}@Overridepublic String getDescription() {return model + "(" + display + ")";}}
package com.project3.domain;public class NoteBook implements Equipment{private String model;private double price;public NoteBook() {super();}public NoteBook(String model, double price) {super();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;}@Overridepublic String getDescription() {return model + "(" + price + ")";}}
package com.project3.domain;public class Printer implements Equipment{private String name;private String type;//机器的类型public Printer() {super();}public Printer(String name, String type) {super();this.name = name;this.type = type;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}@Overridepublic String getDescription() {return name + "(" + type + ")";}}
(4)Employee类及其子类的设计
package com.project3.domain;import com.project3.service.Status;public class Employee {private int id;private String name;private int age;private double salary;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public Employee() {super();}public Employee(int id, String name, int age, double salary) {super();this.id = id;this.name = name;this.age = age;this.salary = salary;}public String getDetails() {return id + "\t" + name + "\t" + age + "\t" + salary ;}@Overridepublic String toString() {return getDetails();}
}
package com.project3.domain;import java.util.jar.Attributes.Name;import com.project3.service.Status;public class Programmer extends Employee{private int memberId;//成员加入开发团队后在团队中的IDprivate Status status = Status.FREE;private 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 Programmer() {super();}public Programmer(int id, String name, int age, double salary, Equipment equipment) {super(id, name, age, salary);this.equipment = equipment;}@Overridepublic String toString() {return getDetails() + "\t程序员\t" + status + "\t \t" + equipment.getDescription();}public String getTeamBaseDetails() {return memberId + "/" + getId() + "\t" + getName() + "\t" + getAge() + "\t" + getSalary();}public String getDetailsForTeam() {return getTeamBaseDetails() + "\t程序员"; }
}
package com.project3.domain;import com.project3.service.Status;public class Designer extends Programmer{private double bonus;//奖金public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}public Designer() {super();}public Designer(int id, String name, int age, double salary, Equipment equipment, double bonus) {super(id, name, age, salary, equipment);this.bonus = bonus;}@Overridepublic String toString() {return getDetails() + "\t设计师\t" + getStatus() + "\t" + bonus + "\t\t" + getEquipment().getDescription();}public String getDetailsForTeam() {return getTeamBaseDetails() + "\t设计师" + "\t" + getBonus(); }
}
package com.project3.domain;public class Architect extends Designer{private int stock;//表示公司奖励的股票数量public int getStock() {return stock;}public void setStock(int stock) {this.stock = stock;}public Architect() {super();}public Architect(int id, String name, int age, double salary, Equipment equipment, double bonus, int stock) {super(id, name, age, salary, equipment, bonus);this.stock = stock;}@Overridepublic String toString() {return getDetails() + "\t架构师\t" + getStatus() + "\t" + getBonus() + "\t" + stock + "\t" + getEquipment().getDescription();}public String getDetailsForTeam() { return getTeamBaseDetails() + "\t架构师" + getBonus() + "\t" + getStock(); }
}
package com.project3.service;
/*** * @Description 员工的状态* @author liermin Email:779679458@qq.com* @version* @date Oct 17, 2022 11:23:18 AM**/
public class Status {private final String NAME;private Status(String name) {this.NAME = name;}public static final Status FREE = new Status("FREE");public static final Status VOCATION = new Status("VOCATION");//休假public static final Status BUSY = new Status("BUSY");public String getNAME() {return NAME;}@Overridepublic String toString() {return NAME;}
}
(5)NameListService类的设计
package com.project3.service;import java.util.Iterator;import com.project3.domain.*;
/*** * @Description 负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]的方法。* @author liermin Email:779679458@qq.com* @version v1.0* @date Oct 17, 2022 11:28:58 AM**/
public class NameListService {public static void main(String[] args) {}private Employee[] employees;/*** 给数组及数组元素进行初始化*/public NameListService(){employees = new Employee[Data.EMPLOYEES.length];//初始化数组for(int i = 0; i < employees.length;i++) {//获取员工类型:普通员工、程序员、设计师、架构师int type = Integer.parseInt(Data.EMPLOYEES[i][0]);//String转化为int//获取员工基本信息:id,name,age,salaryint id = Integer.parseInt(Data.EMPLOYEES[i][1]);//String转化为intString name = Data.EMPLOYEES[i][2];int age = Integer.parseInt(Data.EMPLOYEES[i][3]);//String转化为intdouble salary = Double.parseDouble(Data.EMPLOYEES[i][4]);//String转化为doubleEquipment equipment;double bonus;int stock;switch (type) {case Data.EMPLOYEE:employees[i] = new Employee(id, name, age, salary);break;case Data.PROGRAMMER:equipment = creatEquipment(i);//包装employees[i] = new Programmer(id, name, age, salary, equipment);break;case Data.DESIGNER:equipment = creatEquipment(i);//包装bonus = Double.parseDouble(Data.EMPLOYEES[i][5]) ;employees[i] = new Designer(id, name, age, salary, equipment, bonus);break;case Data.ARCHITECT:equipment = creatEquipment(i);//包装bonus = Double.parseDouble(Data.EMPLOYEES[i][5]) ;stock = Integer.parseInt(Data.EMPLOYEES[i][6]);employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock);break;}}}/*** * @Description 获取指定index位置上员工的设备* @author liermin* @date Oct 17, 2022 5:15:21 PM* @param index* @return*/private Equipment creatEquipment(int index) {//获取设备类型int type = Integer.parseInt(Data.EQUIPMENTS[index][0]); String model = Data.EQUIPMENTS[index][1];switch (type) {case Data.PC:String display = Data.EQUIPMENTS[index][2];return new PC(model, display);case Data.NOTEBOOK:double price = Double.parseDouble(Data.EQUIPMENTS[index][2]);return new NoteBook(model, price );case Data.PRINTER:String name = Data.EQUIPMENTS[index][1];return new Printer(name, Data.EQUIPMENTS[index][2]);}return null;}/*** * @Description 获取当前所有员工* @author liermin* @date Oct 17, 2022 5:40:35 PM* @return*/public Employee[] getAllEmployees() {return employees;}/*** * @Description 获取指定ID的员工* @author liermin * @date Oct 17, 2022 5:40:54 PM* @param id* @return* @throws TeamException */public Employee getEmployee(int id) throws TeamException{for(int i = 0; i < employees.length;i++) {if (employees[i].getId() == id) {return employees[i];}}throw new TeamException("该员工不存在");}}
(6)TeamService类的设计
package com.project3.service;import java.util.Iterator;import com.project3.domain.Architect;
import com.project3.domain.Designer;
import com.project3.domain.Employee;
import com.project3.domain.Programmer;/*** * @Description 关于开发团队成员的管理:添加、删除等。* @author liermin Email:779679458@qq.com* @version* @date Oct 17, 2022 8:31:28 PM**/
public class TeamService {private static int counter = 1;//给memberId赋值private final int MAX_MEMBER = 5;//开发团队最大成员数private Programmer[] team = new Programmer[MAX_MEMBER];//team数组:用来保存当前团队中的各成员对象 private int total = 0;//total:记录团队成员的实际人数public TeamService() {super();}/*** * @Description 返回当前团队的所有对象* @author liermin* @date Oct 17, 2022 9:34:56 PM* @return*/public Programmer[] getTeam() {Programmer[] team = new Programmer[total];for(int i = 0;i < team.length;i++) {team[i] = this.team[i];}return team;}/*** * @Description 团队中添加成员* @author liermin* @date Oct 17, 2022 9:38:52 PM* @param e* @throws TeamException*/public void addMember(Employee e) throws TeamException{
// 成员已满,无法添加if(total >= MAX_MEMBER) {throw new TeamException("成员已满,无法添加");}
// 该成员不是开发人员,无法添加if(!(e instanceof Programmer)) {throw new TeamException("该成员不是开发人员,无法添加");}
// 该员工已在本开发团队中if(isExist(e)) {throw new TeamException("该员工已在本开发团队中");}
// 该员工已是某团队成员
// 该员工正在休假,无法添加Programmer p = (Programmer)e;//强转
// if (p.getStatus().getNAME().equals("BUSY")) {//有可能出现空指针异常if ("BUSY".equals(p.getStatus().getNAME())) {//一定不会出现空指针异常throw new TeamException("该员工已是某团队成员");}else if ("VOCATION".equalsIgnoreCase(p.getStatus().getNAME())) {//忽略大小写throw new TeamException("该员工正在休假");}
// 团队中至多只能有一名架构师
// 团队中至多只能有两名设计师
// 团队中至多只能有三名程序员//获取team已有的成员中架构师、设计师、程序员的个数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] instanceof Programmer) {numOfPro++;}}if (p instanceof Architect) {if (numOfArch >= 1) {throw new TeamException("团队中至多只能有一名架构师");}}else if (p instanceof Designer) {if (numOfDes >= 2) {throw new TeamException("团队中至多只能有两名设计师");}}else if (p instanceof Programmer) {if (numOfPro >= 3) {throw new TeamException("团队中至多只能有三名程序员");}}//将p添加到线头的team中team[total++] = p;//p的属性赋值p.setStatus(Status.BUSY);p.setMemberId(counter++);}/*** * @Description 判断指定员工是否已加入该团队* @author liermin* @date Oct 17, 2022 10:06:27 PM* @param e* @return*/private boolean isExist(Employee e) {for(int i = 0;i < total;i++) {if (team[i].getId() == e.getId()) {return true;}}return false;}/*** * @Description 从团队中删除成员* @author liermin* @date Oct 17, 2022 9:39:02 PM* @param memberId* @throws TeamException*/public void removeMember(int memberId) throws TeamException{int i = 0;//查找for(;i < total;i++) {if (team[i].getMemberId() == memberId) {team[i].setStatus(Status.FREE);break;}}//没找到if(i == total) {throw new TeamException("该员工不存在,删除失败");}//找到了,删除:后一个覆盖前一个for(int j = i;j < total - 1;j++) {team[j] = team[j - 1];}team[total - 1] = null;total--;}
}
(7)TeamView类的设计
package com.project3.view;import com.project3.domain.Employee;
import com.project3.domain.Programmer;
import com.project3.service.NameListService;
import com.project3.service.TeamException;
import com.project3.service.TeamService;public class TeamView {private NameListService listSvc = new NameListService();private TeamService teamSvc = new TeamService();/*** * @Description 主界面显示及控制方法* @author liermin* @date Oct 17, 2022 11:14:10 PM*/public void enterMainMenu() {boolean isFlag = true;char menu = 0;while (isFlag) {if (menu != '1') {listAllEmployees();}System.out.print(" 1-团队列表 2-添加团队成员 3-删除团队成员 4-退出\n");System.out.print("请选择(1-4):");menu = TSUtility.readMenuSelection();switch (menu) {case '1':getTeam();break;case '2':addMember();break;case '3':deleteMember();break;case '4':
// System.out.println("退出");System.out.print("是否确定退出(Y/N)");char isExit = TSUtility.readConfirmSelection();if (isExit == 'Y') {isFlag = false;}break;}}}/*** * @Description 以表格形式列出公司所有成员* @author liermin* @date Oct 17, 2022 11:14:20 PM*/public void listAllEmployees() {System.out.println("---------------------------------开发团队调度软件---------------------------------\n");Employee[] employees = listSvc.getAllEmployees();if ( employees.length == 0) {System.out.println("没有员工信息");} else {System.out.println("ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t领用设备");for (int i = 0; i < employees.length; i++) {System.out.println(employees[i]);}}System.out.println("-----------------------------------------------------------------------------\n");}/*** * @Description 显示团队成员列表操作* @author liermin* @date Oct 17, 2022 11:14:29 PM*/public void getTeam() {System.out.println("---------------------------------团队成员列表---------------------------------\n");Programmer[] team = teamSvc.getTeam();if (team == null || team.length ==0) {System.out.println("开发团队目前没有成员");}else {System.out.println("ID\t姓名\t年龄\t工资\t职位\t奖金\t股票\n");for (int i = 0; i < team.length; i++) {System.out.println(team[i].getDetailsForTeam());}}System.out.println("--------------------------------------------------------------------------\n");}/*** * @Description 实现添加成员操作* @author liermin* @date Oct 17, 2022 11:14:38 PM*/public void addMember() {System.out.println("---------------------------------添加团队成员---------------------------------\n");System.out.print("请输入要加入成员的ID:");int id = TSUtility.readInt();try {Employee employee = listSvc.getEmployee(id);teamSvc.addMember(employee);System.out.println("添加成功");} catch (TeamException e) {System.out.println("添加失败,原因:" + e.getMessage());}TSUtility.readReturn();}/*** * @Description 实现删除成员操作* @author liermin* @throws TeamException * @date Oct 17, 2022 11:14:46 PM*/public void deleteMember() {System.out.println("---------------------------------删除团队成员---------------------------------\n");System.out.print("请输入要删除成员的TID:");int memberid = TSUtility.readInt();System.out.print("是否确定删除(Y/N)");char isDelete = TSUtility.readConfirmSelection();if (isDelete == 'n') {return;}else {try {teamSvc.removeMember(memberid);System.out.println("删除成功");} catch (Exception e) {System.out.println("删除失败,原因:" + e.getMessage());}}TSUtility.readReturn();}public static void main(String[] args) {TeamView view = new TeamView();view.enterMainMenu();}
}
(8)TeamException类的设计
package com.project3.service;
/*** * @Description 自定义异常* @author liermin Email:779679458@qq.com* @version* @date Oct 17, 2022 5:44:47 PM**/
public class TeamException extends Exception{static final long serialVersionUID = -3387514229948L;public TeamException() {super();}public TeamException(String msg) {super(msg);}
}