需求分析:
模拟实现一个基于文本界面的《团队人员调度软件》;
软件启动时,根据给定的数据创建公司部分成员列表;
根据菜单提示,基于现有的公司成员,组建一个开发团队以开发一个新的项目;
组建过程包括成员的添加,删除,查找,在实现功能同时要保证程序的健壮性;
开发团队最多包括一名架构师,两名设计师,三名程序员。
涉及到的知识点:
类的继承和多态;
对象关联:目的是想让一个类的对象方便地使用另外一个对象;
static和final修饰符;
特殊类的属性;
异常处理;
软件设计结构:
view(TeamView),service(TeamException、CompanyService、TeamService),domain(Employee),main(TeamMain)
com.hike.team.domain 实体包
Employee 父类
属性:
id:int
name:String
age:int
salary:double
Programmer 子类
属性:
equipment:Equipment
status:Status //状态
memberId:int
Designer 子类
属性:
bonus:double //奖金
Architect 子类
属性:
stock:int //股票
Equipment 接口
+ abstract getDescription ():String
PC
model:String //型号
display:String //显示器
NoteBook
model:String
price:double
Printer
type:String
name:String
com.hike.team.service 最核心的实体管理器
TeamException 项目自定义异常
CompanyService 公司员工管理器
TeamService 团队管理器
Status 成员的状态,枚举
Data 基础数据
com.hike.team.view UI模块,负责连接用户和管理器
TeamView 主控模块
com.hike.team.main 程序入口
TeamMain
TSUtility 工具类
实体类:
Employee 类:
package com.hike.team.domain;
public class Employee {
private int id;
private String name;
private int age;
private double salary;
public Employee() {
}
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 "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
programmer类:
package com.hike.team.domain;
import com.hike.team.service.Status;
public class Programmer extends Employee{
private int memberId;
private Status status;
private Equipment equipment;
public Programmer() {
super();
}
public Programmer(int id,
String name,
int age,
double salary,
int memberId,
Status status,
Equipment equipment) {
super(id, name, age, salary);
this.memberId = memberId;
this.status = status;
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;
}
@Override
public String toString() {
return super.toString() +
"Programmer{" +
"memberId=" + memberId +
", status=" + status +
", equipment=" + equipment +
'}';
}
}
Designer类:
package com.hike.team.domain;
import com.hike.team.service.Status;
public class Designer extends Programmer{
private double bonus;
public Designer() {
}
public Designer(int id,
String name,
int age,
double salary,
int memberId,
Status status,
Equipment equipment,
double bonus) {
super(id, name, age, salary, memberId, status, equipment);
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public String toString() {
return super.toString() +
"Designer{" +
"bonus=" + bonus +
'}';
}
}
Architect类:
package com.hike.team.domain;
import com.hike.team.service.Status;
public class Architect extends Designer{
private int shock;
public Architect() {
super();
}
public Architect(int id,
String name,
int age,
double salary,
int memberId,
Status status,
Equipment equipment,
double bonus,
int shock) {
super(id, name, age, salary, memberId, status, equipment, bonus);
this.shock = shock;
}
public int getShock() {
return shock;
}
public void setShock(int shock) {
this.shock = shock;
}
@Override
public String toString() {
return super.toString() +
"Architect{" +
"shock=" + shock +
'}';
}
}
Equipment接口:
package com.hike.team.domain;
public interface Equipment {
String getDescription();
}
NoteBook类:
package com.hike.team.domain;
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 toString() {
return "NoteBook{" +
"model='" + model + '\'' +
", price=" + price +
'}';
}
@Override
public String getDescription() {
return toString();
}
}
PC类:
package com.hike.team.domain;
public class PC implements Equipment{
private String model;
private String display;
public PC() {
}
public PC(String model, String display) {
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;
}
@Override
public String toString() {
return "PC{" +
"model='" + model + '\'' +
", display='" + display + '\'' +
'}';
}
@Override
public String getDescription() {
return toString();
}
}
Printer类:
package com.hike.team.domain;
public class Printer implements Equipment{
private String type;
private String name;
public Printer() {
}
public Printer(String type, String name) {
this.type = type;
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Printer{" +
"type='" + type + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public String getDescription() {
return toString();
}
}
CompanyService类:
package com.hike.team.service;
import com.hike.team.domain.*;
public class CompanyService {
//多态数组,保存所有设备信息(电脑,笔记本,打印机)
private Equipment[] equipments;
//多态数组,保存所有的员工信息(程序员,设计师,架构师)
private Employee[] employees;
//获取所有设备信息
public CompanyService(){
//自动导入数据,数据在Data类中
//处理设备对象
this.equipments = new Equipment[Data.EQUIPMENTS.length];
for(int i = 0; i < Data.EQUIPMENTS.length; i++){
String[] child = Data.EQUIPMENTS[i];
if(child.length == 0){
continue;
}
//取识别码,就是子数组下表为0的元素
int code = Integer.parseInt(child[0]);
//穷举识别码,不同的识别码创建不同的对象,所有对象保存在equipments数组中
switch (code){
case Data.PC:
equipments[i] = new PC(child[1],child[2]);
break;
case Data.NOTEBOOK:
equipments[i] = new NoteBook(child[1],Integer.parseInt(child[2]));
break;
case Data.PRINTER:
equipments[i] = new Printer(child[1],child[2]);
break;
}
}
/*在service模块中不要打印
for(Equipment equipment : equipments){
System.out.println(equipment);
}
*/
this.employees = new Employee[Data.EMPLOYEES.length];
for(int i = 0; i < Data.EMPLOYEES.length; i++){
String[] child = Data.EMPLOYEES[i];
//取识别码,穷举识别码,不同的识别码创建不同的对象,所有的对象存储在employees数组中
int code = Integer.parseInt(child[0]);
int id = Integer.parseInt(child[1]);
String name = child[2];
int age = Integer.parseInt(child[3]);
double salary = Integer.parseInt(child[4]);
int memberId = 0;
Status status = Status.FREE;
if((int)(Math.random() * 10) % 7 == 0){
status = Status.VOCATION;
}
Equipment equipment = equipments[i];
switch (code){
case Data.EMPLOYEE:
this.employees[i] = new Employee(id,name,age,salary);
break;
case Data.PROGRAMMER:
this.employees[i] = new Programmer(id,name,age,salary,memberId,status,equipment);
break;
case Data.DESIGNER:
double bonus = Integer.parseInt(child[5]);
this.employees[i] = new Designer(id,name,age,salary,memberId,status,equipment,bonus);
break;
case Data.ARCHITECT:
bonus = Integer.parseInt(child[5]);
int stock = Integer.parseInt(child[6]);
this.employees[i] = new Architect(id,name,age,salary,memberId,status,equipment,bonus,stock);
break;
}
}
/*
for(Employee employee : employees){
System.out.println(employee);
} */
}
//获取所有员工信息
public Employee[] getAllEmployees() {
return employees;
}
//根据id获取某一个员工信息,提示:找不到员工时如何处理
public Employee getEmployee(int id) throws TeamException{
//遍历员工数组,如果员工数组的id和参数id相同,返回某员工信息
for(int i = 0; i < employees.length; i++){
if(employees[i].getId() == id){
return employees[i];
}
}
//循环结束后,直接抛出异常
throw new TeamException("[" + id + "]not found");
}
}
TeamService类:
package com.hike.team.service;
import com.hike.team.domain.Architect;
import com.hike.team.domain.Designer;
import com.hike.team.domain.Employee;
import com.hike.team.domain.Programmer;
public class TeamService {
private static int counter = 1; //给新来的成员赋予TID
public final int MAX_MEMBER = 6; //每个团队最多六人
private Programmer[] team = new Programmer[MAX_MEMBER]; //核心数组存储
private int realCount = 0; //真实的员工数量
//向团队中添加成员,添加失败时如何处理?
public void addMember(Employee e) throws TeamException {
if(realCount == team.length){
throw new TeamException("团队已经达到最大人数,无法添加");
}
if(!(e instanceof Programmer)){
throw new TeamException("该成员不是开发成员,无法添加");
}
Programmer programmer = (Programmer)e;
if(programmer.getMemberId() != 0){
throw new TeamException("该成员已是团队成员,无法添加");
}
if(programmer.getStatus() == Status.VOCATION) {
throw new TeamException("该成员正在休假,无法添加");
}
int architect = 0;
int designer = 0;
int programmers = 0;
for(int i = 0; i < realCount; i++){
if(team[i] instanceof Architect){
architect++;
} else if(team[i] instanceof Designer){
designer++;
}else{
programmers++;
}
}
if(programmer instanceof Architect ) {
if(architect == 1) {
throw new TeamException("团队中只能有一名架构师,无法添加");
}
}else if(programmer instanceof Designer) {
if(designer == 2) {
throw new TeamException("团队中只能有两名设计师,无法添加");
}
}else{
if(programmers == 3) {
throw new TeamException("团队中只能有三名程序员,无法添加");
}
}
//给新成员赋予TID,并改状态
programmer.setMemberId(counter++);
programmer.setStatus(Status.BUSY);
//把参数中的对象保存在数组中,下标由计数器控制
this.team[realCount++] = programmer;
}
//返回当前团队所有有效对象,数组大小与成员人数一致
public Programmer[] getTeam(){
//创建新数组,容量是真实团队人数
Programmer[] newArr = new Programmer[realCount];
//依次把内部数组中所有有效对象保存在新数组中
for(int i = 0; i < realCount; i++){
newArr[i] = this.team[i];
}
return newArr;
}
//从团队中删除成员,删除失败怎么处理?
public void removeMember(int memberID) throws TeamException{
int index = -1;
for(int i = 0; i < realCount; i++){
if(team[i].getMemberId() == memberID){
index = i;
break;
}
}
if(index == -1){
throw new TeamException("未找到指定Tid[" + memberID + "]的成员");
}
//删除前,将删除对象的TID,状态修改
team[index].setMemberId(0);
team[index].setStatus(Status.FREE);
//将要删除的下标位置设置为空洞
team[index] = null;
for(int i = index; i < realCount - 1; i++){
team[i] = team[i + 1];
}
//最右侧有效数据设置为空洞,调整计数器
team[--realCount] = null;
}
}
Data类:
package com.hike.team.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, 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"},
{"13", "23", "邓超", "20", "15000", "20000", "5000"}
};
//PC :21, model, display
//NoteBook:22, model, price
//Printer :23, type, name
public static final String[][] EQUIPMENTS = {
{},
{"22", "联想Y5", "6000"},
{"21", "宏碁 ", "AT7-N52"},
{"21", "戴尔", "3800-R33"},
{"23", "激光", "佳能 2900"},
{"21", "华硕", "K30BD-21寸"},
{"21", "海尔", "18-511X 19"},
{"23", "针式", "爱普生20K"},
{"22", "惠普m6", "5800"},
{"21", "联想", "ThinkCentre"},
{"21", "华硕","KBD-A54M5 "},
{"22", "惠普m6", "5800"},
{"21", "苹果垃圾筒", "Apple32寸"}
};
}
Status类:
package com.hike.team.service;
public enum Status {
FREE, BUSY, VOCATION
}
TeamException类:
package com.hike.team.service;
public class TeamException extends Exception{
public TeamException(String message) {
super(message);
}
public TeamException(Throwable cause) {
super(cause);
}
}
TeamView类:
package com.hike.team.view;
import com.hike.team.domain.Employee;
import com.hike.team.domain.Programmer;
import com.hike.team.service.CompanyService;
import com.hike.team.service.TeamException;
import com.hike.team.service.TeamService;
import org.omg.Messaging.SyncScopeHelper;
public class TeamView {
//关联员工和团队管理器
private CompanyService companyService = new CompanyService();
private TeamService teamService = new TeamService();
//进入总菜单
public void enterMainMenu(){
boolean loopFlag = true;
while(loopFlag){
listAllEmployee();
System.out.println("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4) :");
char selection = TSUtility.readMenuSelection();
switch (selection){
case '1': listTeam();break;
case '2': addMember();break;
case '3': deleteMember();break;
case '4': loopFlag = false;break;
}
}
}
//列出所有员工
private void listAllEmployee(){
System.out.println("-----------------------开发团队调度软件-----------------------");
System.out.println("ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t领用设备");
Employee[] allEmployees = companyService.getAllEmployees();
for(Employee employee : allEmployees){
System.out.println(employee);
}
System.out.println("-------------------------------------------------------------");
}
//添加成员到团队中
private void addMember(){
System.out.println("-------------------------添加团队成员-------------------------");
System.out.println("请输入要添加的员工ID");
int id = TSUtility.readInt();
//获取员工对象
Employee employee = null;
try {
employee = companyService.getEmployee(id);
//把员工对象添加到团队中
teamService.addMember(employee);
System.out.println("添加成功");
} catch (TeamException e) {
System.out.println("添加失败,原因" + e.getMessage());
}
//按回车键继续
TSUtility.readReturn();
}
//删除团队成员
private void deleteMember(){
System.out.println("-------------------------删除团队成员-------------------------");
System.out.println("请输入要删除的员工ID");
int tid = TSUtility.readInt();
System.out.println("确认是否删除(Y/N):");
char confirm = TSUtility.readConfirmSelection();
if(confirm == 'Y'){
try {
teamService.removeMember(tid);
System.out.println("删除成功");
} catch (TeamException e) {
System.out.println("删除失败,原因:" + e.getMessage());
}
TSUtility.readReturn();
}
}
//列出所有团队
private void listTeam(){
System.out.println("-------------------------团队成员列表-------------------------");
System.out.println();
System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t奖金\t股票");
//获取团队
Programmer[] team = teamService.getTeam();
for(Programmer programmer : team){
System.out.println(programmer.toString2());
}
System.out.println("-------------------------------------------------------------");
}
}
TSUtility类:
package com.hike.team.view;
import java.util.*;
public class TSUtility {
private static Scanner scanner = new Scanner(System.in);
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;
}
public static void readReturn() {
System.out.print("按回车键继续...");
readKeyBoard(100, true);
}
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;
}
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;
}
}
TeamMain类:
package com.hike.team.main;
import com.hike.team.domain.*;
import com.hike.team.service.CompanyService;
import com.hike.team.service.Status;
import com.hike.team.service.TeamException;
import com.hike.team.view.TeamView;
public class TeamMain {
public static void main(String[] args) {
new TeamView().enterMainMenu();
}
public static void main2(String[] args){
CompanyService companyService = new CompanyService();
Employee[] employees = companyService.getAllEmployees();
for(Employee employee : employees){
System.out.println(employee);
}
System.out.println("************************************");
Employee employee = null;
try {
employee = companyService.getEmployee(200);
System.out.println(employee);
} catch (TeamException e) {
System.out.println(e.getMessage());
}
}
public static void main1(String[] args) {
Employee e1 = new Employee(1, "张三", 30, 3000);
System.out.println(e1);
Equipment equipment1 = new NoteBook("戴尔", 20000);
Employee e2 = new Programmer(2,"李四",25,5000,0, Status.FREE, equipment1);
System.out.println(e2);
Equipment equipment2 = new PC("戴尔","DE200");
Employee e3 = new Designer(3,"王五",40,12000,0,Status.FREE,equipment2, 5000);
System.out.println(e3);
Equipment equipment3 = new Printer("戴尔", "HP L 2020");
Employee e4 = new Architect(4, "赵六", 45, 30000, 0, Status.FREE, equipment3, 6000, 300);
System.out.println(e4);
}
}