项目三(开发团队调度软件)
整体结构
工具包
Date类(员工数据)
1 package day2_1_project3.util; 2 3 public class Data { 4 public static final int EMPLOYEE = 10; 5 public static final int PROGRAMMER = 11; 6 public static final int DESIGNER = 12; 7 public static final int ARCHITECT = 13; 8 9 public static final int PC = 21; 10 public static final int NOTEBOOK = 22; 11 public static final int PRINTER = 23; 12 13 //Employee(一般员工): 10,id,name,age,salary 14 //Programmer(程序员): 11,id,name,age,salary 15 //Designer(设计师): 12,id,name,age,salary,bonus 16 //Architect(架构师): 13,id,name,age,salary,bonus,stock 17 public static final String[][] EMPLOYEES = { 18 {"10","1","马云","22","3000"}, 19 {"13","2","马化腾","32","18000","15000","2000"}, 20 {"11","3","李彦宏","23","7000"}, 21 {"11","4","刘强东","24","7300"}, 22 {"12","5","雷军","28","10000","5000"}, 23 {"11","6","任志强","22","6800"}, 24 {"12","7","柳传志","29","10800","5200"}, 25 {"13","8","杨元庆","30","19800","15000","2500"}, 26 {"12","9","史玉柱","26","3000","5500"}, 27 {"11","10","丁磊","21","6600"}, 28 {"11","11","张朝阳","25","7100"}, 29 {"12","12","杨志远","27","9600","4800"} 30 }; 31 32 //如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应 33 //PC :21,model,display 34 //NoteBook:22,model,price 35 //Printer :23,name,type 36 public static final String[][] EQUIPMENTS = { 37 {}, 38 {"22","联想T4","6000"}, 39 {"21","戴尔","NEC17寸"}, 40 {"21","戴尔","三星17寸"}, 41 {"23","佳能2900","激光"}, 42 {"21","华硕","三星17寸"}, 43 {"21","华硕","三星17寸"}, 44 {"23","爱普生20K","针式"}, 45 {"22","普惠m6","5800"}, 46 {"21","戴尔","NEC17寸"}, 47 {"21","华硕","三星17寸"}, 48 {"22","普惠m6","5800"}, 49 }; 50 }
TSUtility类(读取键盘输入的工具类)
1 package day2_1_project3.util; 2 import java.util.Scanner; 3 public class TSUtility { 4 private static Scanner scanner = new Scanner(System.in); 5 6 /** 7 * 读取键盘输入的菜单序号 8 * @return 9 */ 10 public static char readMenuSelection() { 11 for (; ; ) { 12 String str = readKeyBoard(1,false); 13 char c = str.charAt(0); 14 if (c == '1' || c == '2' || c == '3' || c == '4') { 15 return c; 16 } 17 System.out.print("选择错误,请重新输入:"); 18 } 19 } 20 21 /** 22 * 读取键盘输入字符 23 * @return 24 */ 25 public static char readChar() { 26 for (; ; ) { 27 String str = readKeyBoard(1,false); 28 return str.charAt(0); 29 } 30 } 31 32 public static int readInt() { 33 for (; ; ) { 34 String str = readKeyBoard(2,false); 35 int num = Integer.parseInt(str); 36 return num; 37 } 38 } 39 40 41 public static char readConfirmSelection() { 42 for (; ; ) { 43 String str = readKeyBoard(1,false); 44 char c = str.toUpperCase().charAt(0); 45 if (c == 'Y' || c == 'N') { 46 return c; 47 } 48 System.out.print("选择错误,请重新输入:"); 49 } 50 } 51 52 /** 53 * 按Enter键继续 54 */ 55 public static void readEnter() { 56 System.out.print("按Enter键继续..."); 57 readKeyBoard(100, true); 58 } 59 60 61 /** 62 * 读取键盘输入 63 * @param limit 64 * @return 65 */ 66 private static String readKeyBoard(int limit,boolean enterKey){ 67 String str = ""; 68 while (scanner.hasNextLine() ) { 69 str = scanner.nextLine().trim(); 70 if (str.length() == 0) { 71 if (enterKey) { 72 return str; 73 } 74 System.out.println("请重新输入:"); 75 } else if (str.length() > limit) { 76 System.out.print("输入长度不能大于" + limit + ",请重新输入:"); 77 } else { 78 break; 79 } 80 } 81 return str; 82 } 83 84 }
实体类包
Employee类(一般员工)
1 package day2_1_project3.domain; 2 3 public class Employee { 4 private int id; 5 private String name; 6 private int age; 7 private double salary; 8 9 public Employee() { 10 } 11 12 public Employee(int id, String name, int age, double salary) { 13 this.id = id; 14 this.name = name; 15 this.age = age; 16 this.salary = salary; 17 } 18 19 public int getId() { 20 return id; 21 } 22 23 public void setId(int id) { 24 this.id = id; 25 } 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public int getAge() { 36 return age; 37 } 38 39 public void setAge(int age) { 40 this.age = age; 41 } 42 43 public double getSalary() { 44 return salary; 45 } 46 47 public void setSalary(double salary) { 48 this.salary = salary; 49 } 50 51 public String getDetails() { 52 return id + "\t" + name + "\t" + age + "\t\t" + salary; 53 } 54 55 @Override 56 public String toString() { 57 return getDetails(); 58 } 59 }
Programmer类(程序员)
1 package day2_1_project3.domain; 2 3 import day2_1_project3.service.Status; 4 5 public class Programmer extends Employee { 6 private int memberId;//开发团队中的id 7 //Status.FREE 空闲 8 //Status.BUSY 已加入开发团队 9 //Status.VOCATION 正在休假 10 private Status status = Status.FREE;//默认的状态是FREE 11 private Equipment equipment; //设备 12 13 public Programmer() { 14 } 15 16 public Programmer(int id, String name, int age, double salary, Equipment equipment) { 17 super(id, name, age, salary); 18 this.equipment = equipment; 19 } 20 21 public int getMemberId() { 22 return memberId; 23 } 24 25 public void setMemberId(int memberId) { 26 this.memberId = memberId; 27 } 28 29 public Status getStatus() { 30 return status; 31 } 32 33 public void setStatus(Status status) { 34 this.status = status; 35 } 36 37 public Equipment getEquipment() { 38 return equipment; 39 } 40 41 public void setEquipment(Equipment equipment) { 42 this.equipment = equipment; 43 } 44 45 @Override 46 public String toString() { 47 return getDetails() + "\t程序员\t" + status + "\t\t\t\t\t" + equipment.getDescription(); 48 } 49 50 public String getBaseDetails() { 51 return memberId + "/" + getId() + "\t\t" + getName() + "\t" + getAge() + "\t\t" + 52 getSalary(); 53 } 54 55 public String getDetailsForTeam() { 56 return getBaseDetails() + "\t" + "程序员" + "\t" + status + "\t\t\t\t\t" + equipment.getDescription(); 57 } 58 }
Designer类(设计师)
1 package day2_1_project3.domain; 2 3 public class Designer extends Programmer { 4 private double bonus;//奖金 5 6 public Designer() { 7 } 8 9 public Designer(int id, String name, int age, double salary, Equipment equipment, double bonus) { 10 super(id, name, age, salary, equipment); 11 this.bonus = bonus; 12 } 13 14 public double getBonus() { 15 return bonus; 16 } 17 18 public void setBonus(double bonus) { 19 this.bonus = bonus; 20 } 21 22 @Override 23 public String toString() { 24 return getDetails() + "\t设计师\t" + getStatus() + "\t" + bonus + "\t\t\t" + getEquipment().getDescription(); 25 } 26 27 @Override 28 public String getDetailsForTeam() { 29 return getBaseDetails() + "\t" + "设计师" + "\t" + getStatus() + "\t" + bonus + "\t\t\t" + getEquipment().getDescription(); 30 } 31 }
Architect类(架构师)
1 package day2_1_project3.domain; 2 3 public class Architect extends Designer { 4 private int stock;//股份 5 6 public Architect() { 7 } 8 9 public Architect(int id, String name, int age, double salary, Equipment equipment, double bonus, int stock) { 10 super(id, name, age, salary, equipment, bonus); 11 this.stock = stock; 12 } 13 14 public int getStock() { 15 return stock; 16 } 17 18 public void setStock(int stock) { 19 this.stock = stock; 20 } 21 22 @Override 23 public String toString() { 24 return getDetails() + "\t架构师\t" + getStatus() + "\t" + getBonus() + "\t" + stock +"\t" + getEquipment().getDescription(); 25 } 26 @Override 27 public String getDetailsForTeam() { 28 return getBaseDetails() + "\t" + "架构师" + "\t" + getStatus() + "\t" + getBonus() + "\t" + stock + "\t" + getEquipment().getDescription(); 29 } 30 }
Equipment接口(设备)
1 package day2_1_project3.domain; 2 3 public interface Equipment { 4 String getDescription(); 5 }
NoteBook类(笔记本电脑)
1 package day2_1_project3.domain; 2 3 public class NoteBook implements Equipment { 4 private String model;//机器型号 5 private double price;//机器价格 6 7 @Override 8 public String getDescription() { 9 return model + "(" + price + ")"; 10 } 11 12 public NoteBook() { 13 } 14 15 public NoteBook(String model, double price) { 16 this.model = model; 17 this.price = price; 18 } 19 20 public String getModel() { 21 return model; 22 } 23 24 public void setModel(String model) { 25 this.model = model; 26 } 27 28 public double getPrice() { 29 return price; 30 } 31 32 public void setPrice(double price) { 33 this.price = price; 34 } 35 }
PC类(台式电脑)
1 package day2_1_project3.domain; 2 3 public class PC implements Equipment{ 4 private String model;//机器型号 5 private String display;//显示器名称 6 7 @Override 8 public String getDescription() { 9 return model + "(" + display + ")"; 10 } 11 12 public PC() { 13 } 14 15 public PC(String model, String display) { 16 this.model = model; 17 this.display = display; 18 } 19 20 public String getModel() { 21 return model; 22 } 23 24 public void setModel(String model) { 25 this.model = model; 26 } 27 28 public String getDisplay() { 29 return display; 30 } 31 32 public void setDisplay(String display) { 33 this.display = display; 34 } 35 }
Printer类(打印机)
1 package day2_1_project3.domain; 2 3 public class Printer implements Equipment { 4 private String name;//机器名称 5 private String type;//机器类型 6 7 @Override 8 public String getDescription() { 9 return name + "(" + type + ")"; 10 } 11 12 public Printer(String name, String type) { 13 this.name = name; 14 this.type = type; 15 } 16 17 public Printer() { 18 } 19 20 public String getName() { 21 return name; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 28 public String getType() { 29 return type; 30 } 31 32 public void setType(String type) { 33 this.type = type; 34 } 35 }
service包
NameListService类
1 package day2_1_project3.service; 2 3 import day2_1_project3.domain.*; 4 import static day2_1_project3.util.Data.*; 5 6 7 /** 8 * 负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]的方法 9 */ 10 public class NameListService { 11 private Employee[] employees; 12 13 /** 14 * 1.根据项目提供的Data类构建相应大小的employees数组 15 * 2.再根据Data类中的数据构建不同的对象,包括Employee,Programmer,Designer,Architect 16 * 3.将对象存于数组中 17 */ 18 public NameListService() { 19 this.employees = new Employee[EMPLOYEES.length]; 20 21 for (int i = 0; i < EMPLOYEES.length; i++) { 22 //获取Employee的4个基本信息 23 int id = Integer.parseInt(EMPLOYEES[i][1]); 24 String name = EMPLOYEES[i][2]; 25 int age = Integer.parseInt(EMPLOYEES[i][3]); 26 double salary = Double.parseDouble(EMPLOYEES[i][4]); 27 Equipment equipment; 28 double bonus; 29 30 int type = Integer.parseInt(EMPLOYEES[i][0]); 31 switch (type) { 32 case EMPLOYEE: 33 employees[i] = new Employee(id, name, age, salary); 34 break; 35 case PROGRAMMER: 36 equipment = createEquipment(i); 37 employees[i] = new Programmer(id, name, age, salary, equipment); 38 break; 39 case DESIGNER: 40 equipment = createEquipment(i); 41 bonus = Double.parseDouble(EMPLOYEES[i][5]); 42 employees[i] = new Designer(id, name, age, salary, equipment, bonus); 43 break; 44 case ARCHITECT: 45 equipment = createEquipment(i); 46 bonus = Double.parseDouble(EMPLOYEES[i][5]); 47 int stock = Integer.parseInt(EMPLOYEES[i][6]); 48 employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock); 49 break; 50 } 51 } 52 } 53 54 private Equipment createEquipment(int index) { 55 int key = Integer.parseInt(EQUIPMENTS[index][0]); 56 String modelOrName = EQUIPMENTS[index][1]; 57 switch (key) { 58 case PC://21 59 String display = EQUIPMENTS[index][2]; 60 return new PC(modelOrName,display); 61 case NOTEBOOK://22 62 double price = Double.parseDouble(EQUIPMENTS[index][2]); 63 return new NoteBook(modelOrName,price); 64 case PRINTER://23 65 String type = EQUIPMENTS[index][2]; 66 return new Printer(modelOrName,type); 67 } 68 return null; 69 } 70 71 /** 72 * 获取当前所有员工 73 * @return 74 */ 75 public Employee[] getAllEmployees() { 76 return employees; 77 } 78 79 /** 80 * 获取指定ID的员工对象 81 * @param id 82 * @return 83 */ 84 public Employee getEmployee(int id) throws TeamException { 85 for (int i = 0; i < employees.length; i++) { 86 if (employees[i].getId() == id) { 87 return employees[i]; 88 } 89 } 90 throw new TeamException("找不到指定的员工"); 91 } 92 93 }
TeamService类
1 package day2_1_project3.service; 2 3 import day2_1_project3.domain.Architect; 4 import day2_1_project3.domain.Designer; 5 import day2_1_project3.domain.Employee; 6 import day2_1_project3.domain.Programmer; 7 8 /** 9 * 关于开发团队成员的管理:添加、删除等 10 */ 11 public class TeamService { 12 private static int counter = 1;//用来为开发团队新增成员自动生成团队中的唯一ID,即memberId. 13 private final int MAX_MEMBER = 5;//开发团队最大成员数 14 private Programmer[] team = new Programmer[MAX_MEMBER];//保存当前团队中的各成员对象 15 private int total;//记录团队成员的实际人数 16 17 public TeamService() { 18 } 19 20 /** 21 * 获取开发团队中的所有成员 22 * @return 23 */ 24 public Programmer[] getTeam() { 25 Programmer[] programmers = new Programmer[total]; 26 for (int i = 0; i < total; i++) { 27 programmers[i] = team[i]; 28 } 29 return programmers; 30 } 31 32 /** 33 * 将指定员工添加开发团队中 34 * @param e 35 * @throws TeamException 36 */ 37 public void addMember(Employee e) throws TeamException { 38 if (total >= MAX_MEMBER) { 39 throw new TeamException("团队已满"); 40 } 41 if (!(e instanceof Programmer)) { 42 throw new TeamException("该成员不是开发人员"); 43 } 44 if (isExist(e)) { 45 throw new TeamException("该员工已在本开发团队中"); 46 } 47 Programmer prog = (Programmer)e; 48 //因为Status类没有重写Object的equals()方法,所以下面这个就不要使用了 49 //if (programmer.getStatus().equals(Status.BUSY)){ 50 //下面这两行功能相识,但后者更好,因为equals()方法的调用者"BUSY",确保了不会出现空指针异常 51 //if(programmer.getStatus().getNAME().equals("BUSY")){ 52 if("BUSY".equals(prog.getStatus().getNAME())){ 53 throw new TeamException(" 该员工已在某开发团队中"); 54 }else if ("VOCATION".equals(prog.getStatus().getNAME())) { 55 throw new TeamException(" 该员工正在休假"); 56 } 57 int numOfArch = 0,numOfDes = 0,numOfPro = 0; 58 for (int i = 0; i <total; i++) { 59 if (team[i] instanceof Architect) { 60 numOfArch++; 61 } else if (team[i] instanceof Designer) { 62 numOfDes++; 63 } else { 64 numOfPro++; 65 } 66 } 67 68 //(e instanceof Architect)是true的话,不管(numOfArch >= 1)是true还是false, 69 // 下面的else if和else都不会执行 70 if (e instanceof Architect) { 71 if (numOfArch >= 1) { 72 throw new TeamException("团队中至多只能有一名架构师"); 73 } 74 } else if (e instanceof Designer) { 75 if (numOfDes >= 2) { 76 throw new TeamException("团队中至多只能有两名设计师"); 77 } 78 } else { 79 if (numOfPro >= 3) { 80 throw new TeamException("团队中至多只能有三名程序员"); 81 } 82 } 83 84 85 //如果换成下面的编码,是否可以实现和上面一样的逻辑呢? 86 // if (e instanceof Architect && numOfArch >= 1) { 87 // throw new TeamException("团队中至多只能有一名架构师"); 88 // } else if (e instanceof Designer && numOfDes >= 2) { 89 // throw new TeamException("团队中至多只能有两名设计师"); 90 // } else { 91 // throw new TeamException("团队中至多只能有三名程序员"); 92 // } 93 94 //分析:(e instanceof Architect)是true的话,如果(numOfArch >= 1)是false, 95 // 则下面的else if和else就有可能执行了 96 //举例,如果开发团队只有2个设计师,现在添加一个架构师,则会执行else if()语句 97 //报错"团队中至多只能有两名设计师",但开发团队中并没有架构师,现在添加一名 98 //架构师是完全可以的。所以上面的编码是不正确的 99 100 prog.setStatus(Status.BUSY); 101 prog.setMemberId(counter++); 102 team[total++] = prog; 103 } 104 105 /** 106 * 判断指定的员工是否已经在现有的开发团队中 107 * @param e 108 * @return 109 */ 110 private boolean isExist(Employee e){ 111 for (int i = 0; i < total; i++) { 112 if (e.getId() == team[i].getId()) { 113 return true; 114 } 115 } 116 return false; 117 } 118 119 public void removeMember(int memberId) throws TeamException { 120 for (int i = 0; i < total; i++) { 121 if (memberId == team[i].getMemberId()) { 122 team[i].setStatus(Status.FREE); 123 for (int j = i; j < total-1; j++) { 124 team[j] = team[j + 1]; 125 } 126 team[--total] = null; 127 return; 128 } 129 } 130 throw new TeamException("找不到该成员"); 131 } 132 }
Status 状态类
1 package day2_1_project3.service; 2 3 public class Status { 4 private final String NAME; 5 6 private Status(String name) { 7 this.NAME = name; 8 } 9 public static final Status FREE= new Status("FREE"); 10 public static final Status BUSY= new Status("BUSY"); 11 public static final Status VOCATION= new Status("VOCATION"); 12 13 public String getNAME() { 14 return NAME; 15 } 16 17 @Override 18 public String toString() { 19 return NAME; 20 } 21 }
TeamException 异常类
1 package day2_1_project3.service; 2 3 /** 4 * 自定义异常类 5 */ 6 public class TeamException extends Exception { 7 8 static final long serialVersionUID = -3387513124229948L; 9 10 public TeamException() { 11 } 12 13 public TeamException(String message) { 14 super(message); 15 } 16 }
view包
TeamView类
1 package day2_1_project3.view; 2 3 import day2_1_project3.domain.Employee; 4 import day2_1_project3.domain.Programmer; 5 import day2_1_project3.service.NameListService; 6 import day2_1_project3.service.TeamException; 7 import day2_1_project3.service.TeamService; 8 import day2_1_project3.util.TSUtility; 9 10 public class TeamView { 11 private NameListService listSvs = new NameListService(); 12 private TeamService teamSvs = new TeamService(); 13 14 /** 15 * 主界面显示及控制方法 16 */ 17 public void enterMainMenu(){ 18 boolean loopFlag = true; 19 char menu = 0; 20 while (loopFlag) { 21 if (menu != '1') { 22 listAllEmployees(); 23 } 24 System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):"); 25 menu = TSUtility.readMenuSelection(); 26 switch (menu) { 27 case '1': 28 getTeam(); 29 break; 30 case '2': 31 addMember(); 32 break; 33 case '3': 34 deleteMember(); 35 break; 36 case '4': 37 System.out.print("确认是否退出(Y/N):"); 38 char isExit = TSUtility.readConfirmSelection(); 39 if (isExit == 'Y') { 40 loopFlag = false; 41 } 42 } 43 } 44 45 } 46 47 /** 48 * 以表格方式列出公司所有成员 49 */ 50 private void listAllEmployees() { 51 // System.out.println("显示开发团队所有成员"); 52 System.out.println("----------------------------开发团队调度软件----------------------------\n"); 53 Employee[] employees = listSvs.getAllEmployees(); 54 if (employees == null || employees.length == 0) { 55 System.out.println("公司没有任何员工信息!"); 56 } else { 57 System.out.println("ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t领用设备"); 58 for (int i = 0; i < employees.length;i++) { 59 System.out.println(employees[i]); 60 } 61 } 62 System.out.println("-------------------------------------------------------------------------"); 63 } 64 65 /** 66 * 显示团队成员 67 */ 68 private void getTeam() { 69 // System.out.println("团队列表"); 70 System.out.println("----------------------------团队成员列表----------------------------\n"); 71 Programmer[] team = teamSvs.getTeam(); 72 if (team == null || team.length == 0) { 73 System.out.println("开发团队目前没有成员!"); 74 } else { 75 System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t领用设备"); 76 for (int i = 0; i < team.length; i++) { 77 System.out.println(team[i].getDetailsForTeam()); 78 } 79 } 80 System.out.println("-------------------------------------------------------------------------"); 81 } 82 83 /** 84 * 添加成员 85 */ 86 private void addMember(){ 87 // System.out.println("添加成员"); 88 System.out.print("请输入要添加的成员ID:"); 89 int id = TSUtility.readInt(); 90 try { 91 Employee e = listSvs.getEmployee(id); 92 teamSvs.addMember(e); 93 System.out.println("添加成功!"); 94 } catch (TeamException ex) { 95 System.out.println("添加失败,原因:" + ex.getMessage()); 96 } 97 //按Enter键继续 98 TSUtility.readEnter(); 99 } 100 101 /** 102 * 删除成员 103 */ 104 private void deleteMember() { 105 // System.out.println("删除成员"); 106 System.out.print("请输入要删除的成员TID:"); 107 int tid = TSUtility.readInt(); 108 System.out.print("确认是否删除(Y/N):"); 109 char isDelete = TSUtility.readConfirmSelection(); 110 if (isDelete == 'N') { 111 return; 112 } 113 try { 114 teamSvs.removeMember(tid); 115 System.out.println("删除成功!"); 116 } catch (TeamException e) { 117 System.out.println("添加失败,原因:" + e.getMessage()); 118 } 119 TSUtility.readEnter(); 120 } 121 122 public static void main(String[] args) { 123 TeamView view = new TeamView(); 124 view.enterMainMenu(); 125 } 126 }