软件设计结构
View模块为主控模块,负责菜单的显示和处理用户的操作。
Service模块为实体对象的管理模块。NameListService和TeamService类分别用各自的数组来管理公司员工和开发团队的成员。
domain模块为Employee及其子类还要Equipm以及实现类和JavaBean类所在的包。
###1、domain模块所有实体类关系
Employee类代码
public class Employee { private int id; private String name; private int age; private double salary; public Employee(int id, String name, int age, double salary) { this.id = id; this.name = name; this.age = age; this.salary = 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; } @Override public String toString() { return id +"\t"+name +"\t" + age +"\t\t" + salary +"\t" ; } }
Programmer类代码
public class Programmer extends Employee{ private int memberID; Status status=Status.FREE; Equipment equipment; 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; } @Override public String toString() { return super.toString() + "程序员"+"\t"+getStatus()+ "\t\t\t\t\t"+equipment.getDescription(); } }
Designer类代码
public class Designer extends Programmer{ private double bonus; public Designer(int id, String name, int age, double salary, Equipment equipment, double bonus) { super(id, name, age, salary, equipment); this.bonus = bonus; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } @Override public String toString() { return getId()+"\t"+getName()+"\t"+getAge()+"\t\t"+getSalary()+"\t"+"设计师"+"\t"+getStatus()+"\t"+bonus+"\t\t\t"+equipment.getDescription(); } }
Architect类代码
public class Architect extends Designer{ private int stock; 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; } @Override public String toString() { return getId()+"\t"+getName()+"\t"+getAge()+"\t\t"+getSalary()+"\t"+"架构师"+"\t"+getStatus()+"\t"+getBonus()+"\t"+stock+"\t"+equipment.getDescription(); } }
Equipment接口代码
public interface Equipment { public String getDescription(); }
PC实现类代码
public class PC implements Equipment{ private String model; private String display; public PC(String model, String display) { this.model = model; this.display = display; } @Override public String getDescription() { return model+"("+display+")"; } }
NoteBook实现类代码
public class NoteBook implements Equipment{ private String model; private double price; public NoteBook(String model, double price) { this.model = model; this.price = price; } @Override public String getDescription() { return model+"("+price+")"; } }
Printer实现类代码
public class Printer implements Equipment{ private String name; private String type; public Printer(String name, String type) { this.name = name; this.type = type; } @Override public String getDescription() { return name+"("+type+")"; } }
Service模块数据获取和存储
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"} }; }
Status枚举类代码(用来表示员工的状态)
public class Status { private final String NAME; 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 Status(String NAME) { this.NAME = NAME; } @Override public String toString() { return NAME ; } }
TeamException类(用来处理异常)
public class TeamException extends Exception{ private static final long serialVersionUID = 1L; public TeamException() { } /* * * @description:当我处理我的团队异常类的时候,直接将提前写好的信息输出 * @author: zouhuiming * @date: 2023/4/13 9:59 * @param: [message] * @return: **/ public TeamException(String message) { super(message); } }
NameListService类代码(用来读取data类中的数据,并且存储在Employee数组中)
public class NameListService { Employee[] employees; /* * * @description:在该对象初始化的时候将Data类中的数据加载到该对象 * @author: zouhuiming * @date: 2023/4/13 9:33 * @param: [] * @return: **/ public NameListService() { employees=new Employee[Data.EMPLOYEES.length]; for (int i = 0; i <employees.length ; i++) { int type=Integer.parseInt(Data.EMPLOYEES[i][0]); int id=Integer.parseInt(Data.EMPLOYEES[i][1]); String name=Data.EMPLOYEES[i][2]; int age=Integer.parseInt(Data.EMPLOYEES[i][3]); double salary=Double.parseDouble(Data.EMPLOYEES[i][4]); switch (type){ case Data.EMPLOYEE: employees[i]=new Employee(id,name,age,salary); break; case Data.PROGRAMMER: employees[i]=new Programmer(id,name,age,salary,getEquipment(i)); break; case Data.DESIGNER: employees[i]=new Designer(id,name,age,salary,getEquipment(i),Double.parseDouble(Data.EMPLOYEES[i][5])); break; case Data.ARCHITECT: employees[i]=new Architect(id,name,age,salary,getEquipment(i),Double.parseDouble(Data.EMPLOYEES[i][5]),Integer.parseInt(Data.EMPLOYEES[i][6])); break; } } } /* * * @description:获取某个员工的装备 * @author: zouhuiming * @date: 2023/4/13 10:00 * @param: [i] * @return: Project003team.domain.Equipment **/ private Equipment getEquipment(int i) { int type=Integer.parseInt(Data.EQUIPMENTS[i][0]); switch (type){ case Data.PC: return new PC(Data.EQUIPMENTS[i][1],Data.EQUIPMENTS[i][2]); case Data.NOTEBOOK: return new NoteBook(Data.EQUIPMENTS[i][1],Double.parseDouble(Data.EQUIPMENTS[i][2])); case Data.PRINTER: return new Printer(Data.EQUIPMENTS[i][1],Data.EQUIPMENTS[i][2]); } return null; } /* * * @description:获取所有员工对象 * @author: zouhuiming * @date: 2023/4/13 10:01 * @param: [] * @return: Project003team.domain.Employee[] **/ public Employee[] listAllEmployees(){ return employees; } /* * * @description:获取某个员工对象 * @author: zouhuiming * @date: 2023/4/13 10:01 * @param: [id] * @return: Project003team.domain.Employee **/ public Employee getEmployee(int id) throws TeamException{ if (id<0||id>employees.length){ throw new TeamException("找不到指定的员工"); }else { return employees[id]; } } }
TeamService类代码(用与存储开发团成员)
public class TeamService { //自增TeamID private int counter=1; //设置最大团队成员数 private final int MAX_MEMBER=5; //创建Programmer数组来存储团队成员,由于普通的员工不能添加进团队, // 所以就直接设置Programmer对象 private Programmer[] team=new Programmer[MAX_MEMBER]; //显示实时团队人数 private int total=0; /* * * @description:获取所有团队成员 * @author: zouhuiming * @date: 2023/4/13 10:04 * @param: [] * @return: Project003team.domain.Programmer[] **/ public Programmer[] getTeam(){ Programmer[] team=new Programmer[total]; for (int i = 0; i < total; i++) { team[i]=this.team[i]; } return team; } /* * * @description:将员工加入到开发团队中 * @author: zouhuiming * @date: 2023/4/13 10:04 * @param: [e] * @return: void **/ public void addMember(Employee e) throws TeamException { if (total>=5){ throw new TeamException("开发团队成员已满,添加失败"); } if (!(e instanceof Programmer)){ throw new TeamException("该成员不是开发人员,添加失败"); } if (exist(e)){ throw new TeamException("该成员已经在团队中"); } //到这说明待加入对象一定是开发人员 //因为后面设计Status,所有一定要进行强转来获取子类的成员属性 Programmer p=(Programmer) e; //让确定的字符串在前面可以避免空指针异常 if ("BUSY".equals(p.getStatus())){ throw new TeamException("该成员已经在其他团队"); } if ("VOCATION".equals(p.getStatus())){ throw new TeamException("该成员已经在度假"); } //获取团队中程序员、设计师、架构师的数量 int prototal=0,destotal=0,arctotal=0; for (int i = 0; i <total ; i++) { if (team[i] instanceof Architect){ arctotal++; }else if (team[i] instanceof Designer){ destotal++; }else if (team[i] instanceof Programmer){ prototal++; } } if (p instanceof Architect){ if (arctotal>=1){ throw new TeamException("团队中只能有一个架构师"); } } else if (p instanceof Designer) { if (destotal>=2){ throw new TeamException("团队中只能有两个设计师"); } }else { if (prototal>=3){ throw new TeamException("团队中只能有三个程序员"); } } //将该成员加入到开发团队中,total+1 team[total++]=p; //将该成员的状态设置为BUSY p.setStatus(Status.BUSY); //设置该成员的团队ID p.setMemberID(counter++); } /* * * @description:判断成员是否已经在开发团队中 * @author: zouhuiming * @date: 2023/4/13 10:24 * @param: [e] * @return: boolean **/ private boolean exist(Employee e) { for (int i = 0; i <total; i++) { if (team[i].getId()==e.getId()){ return true; } } return false; } /* * * @description:将团队中某个成员从团队中删除 * @author: zouhuiming * @date: 2023/4/13 10:05 * @param: [memberID] * @return: void **/ 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("开发团队中没有此成员"); } //将i之后的每个对象前移一位 for (int j = i; j <total-1 ; j++) { team[j]=team[j+1]; } //将最后一个元素归null team[total--]=null; } }
3、teamview模块,用于和用户交互
TSUtility类代码(封装了许多获取控制台数据的静态方法)
import java.util.Scanner; /** * * @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; } }
TeamView类代码(主要是实现与用户进行交互,也是软件启动类)
public class TeamView { //加载数据,并且存储到Employee数组中 NameListService listSvc=new NameListService(); //加载团队数据,并且存储在Programmer数组中 TeamService teamSvc=new TeamService(); /* * * @description:主菜单 * @author: zouhuiming * @date: 2023/4/13 13:36 * @param: [] * @return: void **/ public void enterMianMenu(){ boolean flag=true; do{ listAllEmployees(); System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):"); char menu=TSUtility.readMenuSelection(); switch (menu){ case '1': try { getTeam(); } catch (TeamException e) { System.out.println(e.getMessage()); } break; case '2': addMember(); break; case '3': deleteMember(); break; case '4': System.out.print("确定要退出吗(Y/N)?"); char isOut=TSUtility.readConfirmSelection(); if (isOut=='Y'){ flag=false; } break; } }while (flag); } /* * * @description:展示所有员工 * @author: zouhuiming * @date: 2023/4/13 13:40 * @param: [] * @return: void **/ public void listAllEmployees(){ System.out.println("*********************公司员工***********************"); System.out.println("ID\t"+"姓名\t"+"年龄\t"+"工资"+"\t"+"职位\t"+"状态\t"+"奖金\t"+"股票\t\t"+"领用设备"); Employee[] employees = listSvc.listAllEmployees(); for (Employee e:employees ) { System.out.println(e); } System.out.println("*********************已经列出所有员工***********************"); } public void getTeam() throws TeamException { Programmer[] team = teamSvc.getTeam(); if (team==null||team.length==0){ throw new TeamException("团队中还没有成员"); }else { System.out.println("*********************开发团队成员***********************"); System.out.println("TID/ID\t"+"姓名\t"+"年龄\t"+"工资"+"\t"+"职位\t"+"状态\t"+"奖金\t"+"股票\t"+"领用设备"); for (int i = 0; i <team.length ; i++) { System.out.println(team[i].getMemberID()+"/"+team[i]); } System.out.println("*********************已经列出所有开发团队成员******************"); } TSUtility.readReturn(); } public void addMember() { System.out.println("********************添加团队成员*****************"); //先输出所有员工 listAllEmployees(); //询问选的员工ID System.out.print("请输入您想要选择的员工ID:"); int ID=TSUtility.readInt(); try { teamSvc.addMember(listSvc.getEmployee(ID-1)); System.out.println("添加成功"); } catch (TeamException e) { System.out.println("添加失败,原因是:"+e.getMessage()); } TSUtility.readReturn(); } public void deleteMember(){ System.out.println("**********************删除团队成员**************************"); try{ getTeam(); } catch (TeamException e) { System.out.println("删除失败,原因是:"+e.getMessage()); } System.out.print("请输入您想要删除的成员TID:"); int id=TSUtility.readInt(); System.out.print("确定要删除吗(Y/N)?"); char isDelete=TSUtility.readConfirmSelection(); if (isDelete=='Y') { try { teamSvc.removeMember(id); System.out.println("删除成功"); TSUtility.readReturn(); } catch (TeamException e) { System.out.println(e.getMessage()); } } } //程序执行入口 public static void main(String[] args) { new TeamView().enterMianMenu(); } }
4、运行截图
1、主界面
2、添加团队成员
3、团队列表
4、删除团队成员
删除之后成员列表
5、退出