开发团队调度系统----java基础知识运用

最近这几天都在跟着做 “开发团队调度系统” 的项目,对面向对象的编程思想有了更加深入的理解,收获很多。
这个系统的主要任务是:从已经给定的公司员工的列表中,选择一定数目(设定的是5人)的员工,加入到 软件开发团队中。
其中,公司的员工股分为不同的种类:employee(普通员工)、programmer(程序员)、designer(设计师)、architect(架构师)。
对于要加入 软件开发团队 中的人,除了总人数设置的有限制之外,还要求:最多有3个程序员(programmer),最多有2个设计师(designer),最多有1个架构师(architect),并且不能有普通员工(employee)。
所以,在向 软件开发团队 中添加公司员工的时候,实际上是有诸多限制的。并不是简单地加进去就可以。
下面就对这个系统的主要设计思想、实现方法,进行简要概述:

软件设计结构

1、该软件主要由以下三个模块组成:
在这里插入图片描述

2、关于domain的设计:
基本的对象类的关系
说明:
(1)公司的员工类之间为继承关系,包含employee(普通员工)、programmer(程序员)、designer(设计师)、architect(架构师)这4类,对应的继承关系如图所示。
(2)公司为员工提供的设备,它们之间的关系并不是继承,但是却拥有一些相同或相似的特点,所以将它们所拥有的相似的特点,抽象出来,作为接口equipment,而公司为员工提供的设备:PC、NoteBook、Printer,则作为接口equipment的实现类。他们之间的实现关系也如上面的图所示。

数据的存储模式

在这里没有采用数据库,而是使用单一的数组来进行数据的暂存。具体的实现方式如下:
(1)将员工employee,和设备equipment,分别作为两个数组来进行存储。这里进行数据存储的数组,用的是string类型的二维数组:[number][],即外围数组的长度是确定的,内存数组的元素是不定的,可以根据存储的数据对应的员工类型的不同,分别确定它们的长度。
(2)最后,整理上面的两个数组元素成为一个数组,并且采用一个employee类的、一维的、对象数组,来进行存储至于每个数组元素所指向的对象的类型,取决于该位置上 对应的员工 的类型。
(3)由于 公司所有员工的数据 最终是存储在一个 一维的对象数组中的,所以 开发团队的员工信息,也应该存储在一个employee类的、一维的、对象数组中。由于限制条件“软件开发团队的成员,至少应该是程序员”,所以,该数组可以定义为programmer类型的 对象数组。


注意:
需要注意的是,对于公司的员工列表中,员工的状态这一项的设计,由于规定的只有free,busy,vocation三个选项,所以可以采取如下方式进行处理:模仿单例模式的方式:定义一个类status,在其中设置属性name,来标记status的值。然后构造三个静态的变量(对象),它们的name值分别为free,busy,vocation ,并在构造器中对他们的name属性进行赋值。之后,将employee数组中的对象的status属性初始化为free,在之后每进行一次状态转换,就对该对象的status属性进行一次手动赋值(状态切换)。

系统的主要代码实现

主要的几个类的代码(包含注释),如下:
1、NameListService

import com.athanchang.team.domain.Architect;
import com.athanchang.team.domain.Designer;
/**
 * 
 * @Description 功能:将Data中的数据封装到Employee[]数组中,
 * 同时提供相关操作Employee[]的方法
 */
import static com.athanchang.team.service.Data.*;
import com.athanchang.team.domain.Employee;
import com.athanchang.team.domain.Equipment;
import com.athanchang.team.domain.NoteBook;
import com.athanchang.team.domain.PC;
import com.athanchang.team.domain.Printer;
import com.athanchang.team.domain.Programmer;

public class NameListService {
//	private static final String[][] EMPLOYEES = null;
	/*
	 * 声明属性employees:用来保存公司所有员工的对象
	 * ------即,展示的数据都放在数组employees当中
	 */
	private Employee[] employees;//是一个属性 数组

	
	/**
	 * 将employees数组填充:
	 * 在NameListService构造器中:
	 * 1、根据项目提供的Data类构建相应大小的employees数组
	 * 2、再根据Data类中的数据构建不同的对象,
	 * 包括Employee、Programmer、Designer和Architect
	 * 3、将对象存于数组中
	 */
	//构造器主要作用:对employees数组,以及数组元素做初始化
	public NameListService() {
		super();
		//初始化数组
		employees = new Employee[Data.EMPLOYEES.length];
		/*
		 * 取决于EMPLOYEES的整个数组,
		 * 从头到尾,根据人家是什么类型的,
		 * 再来造对象
		 */
		//因为是用foe循环;所以,相当于将data类中的所有数据都加入到employees数组中来了
		for(int i=0;i<employees.length;i++) {
			/*
			 * EMPLOYEES[i][0]是string类型
			 * 而EMPLOYEE = 10,是int类型
			 * ------需要将string转化为int
			 */
			//获取员工的类型
			int type = Integer.parseInt(EMPLOYEES[i][0]);
			//获取员工的4个基本信息
			int id = Integer.parseInt(Data.EMPLOYEES[i][1]);//因为id本来是string类型
			String name = EMPLOYEES[i][2];
			int age = Integer.parseInt(EMPLOYEES[i][3]);
			double salary = Double.parseDouble(EMPLOYEES[i][4]);
			/*
			 * 在这里只声明这个变量,不去获取
			 * 因为在这里获取的话,会存在风险:
			 * 例如“马云”,就不存在有设备的情况,
			 * 而相应的createEquipment(int index)中并没有考虑到没有设备的情况怎么处理
			 * 所以在这里,只做声明,不做处理
			 * ------解决了变量重名的问题
			 */
			Equipment equipment;
			double bonus;
			int stock;
			
			switch(type) {
			case Data.EMPLOYEE://10
				employees[i] = new Employee(id, name, age, salary);				
				break;
			case Data.PROGRAMMER://11
				/*
				 * 需要将数组:EQUIPMENTS中的元素转化为对象
				 * ------
				 * 对象又分为好几种
				 * 因为 设备里边有几个具体的实现类
				 * EQUIPMENTS数组的每一列的第一个,不同的字符串表示是不同的设备
				 * ------把它封装到一个方法里
				 */
				equipment = createEquipment(i);
				//i告诉是哪一个的索引位置,对应EQUIPMENTS数组中EQUIPMENTS[i]
				
				employees[i] = new Programmer(id, name, age, salary, equipment);
				break;
			case Data.DESINGER://12
				equipment = createEquipment(i);
				bonus = Double.parseDouble(EMPLOYEES[i][5]);
				employees[i] = new Designer(id, name, age, salary, equipment, bonus);
				break;
			case Data.ARCHITECT://13
				equipment = createEquipment(i);
				bonus = Double.parseDouble(EMPLOYEES[i][5]);
				stock = Integer.parseInt(EMPLOYEES[i][6]);
				employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock);
				
			}
		}
	}
	/**
	 * @ Description 查找第i个位置的员工对应的设备的方法
	 * ------获取指定index上的员工的设备
	 * ----与处理 员工类型 的逻辑有点像
	 */
	private Equipment createEquipment(int index) {
		
		int key = Integer.parseInt(Data.EQUIPMENTS[index][0]);
		/*
		 * 第一个参数都是在外边统一获取的
		 * 第二个参数是自己独立获取的
		 */
		String modelOrName = Data.EQUIPMENTS[index][1];
		switch(key) {
		/*
		 * 注意:细节之处:
		 * 这里,一般case的情况并不直接使用 21、22、23
		 * 可读性非常差,并且改动起来很麻烦
		 * 一般是使用这里的 这种全局常量(static final)来进行标志,更清晰
		 */
		case Data.PC://21
			/*
			 * 要返回一个PC对象
			 * model、display
			 */
			String display = Data.EQUIPMENTS[index][2];
			return new PC(modelOrName, display);
		case Data.NOTEBOOK://22
			/*
			 * 要返回一个NOTEBOOK对象
			 * model、price
			 */
			double price = Double.parseDouble(Data.EQUIPMENTS[index][2]);
			return new NoteBook(modelOrName, price);
		case Data.PRINTER://23
			String type = Data.EQUIPMENTS[index][2];
			return new Printer(modelOrName, type);
			
		}
		return null;
	}

	/**
	 * @ Description 获取当前所有员工
	 * 返回,包含所有员工数组的对象
	 * -------
	 * 因为当前NameListService 类的属性数组
	 * Employee[] emploees
	 * 是私有的,
	 * 这个方法就相当于它的方法
	 */
	public Employee[] getAllEmployees() {
		/*
		 * 
		 * 因为是相当于get方法
		 * ------把员工数组返回一下就行
		 */
		return employees;
	}
	/**
	 * @ Description:
	 * 返回某一个具体的id,对应的employee
	 * ------
	 * 获取指定ID的员工对象
	 * 参数:指定员工的ID
	 * 返回:指定员工对象
	 * 异常:找不到指定的员工
	 */
	public Employee getEmployee(int id) throws TeamException {
		/*
		 * 先在数组找一下,有没有要查找的index对应的员工
		 * ------遍历
		 */
		for(int i=0;i<employees.length;i++) {
			if(employees[i].getId() == id) {
				/*
				 * 这里的id如果是int型----==
				 * 如果是Integer型的话,
				 * 如果用 == ,对的话,是因为:
				 * integer内部定义的integercachae内部类,保存了-128~+127
				 * 是恰好撞上了;
				 * 正常来讲,就应该用equals(id是integer类型的话)
				 *是因为:凡是比较对象,两个对象的数据一样的话,用的都是equals
				 * 对象的时候,==比较的是指向同一个引用
				 */
				return employees[i];
			}	
		}
		/*
		 * 没找到的话,就抛出异常
		 */
		throw new TeamException("找不到指定的员工");
		/*
		 * 先暂时抛出,
		 * 在最后整体调用的时候再try-catch
		 * 进行真正的处理异常
		 */
	}
	
	
	
	
}

2、TeamService类

/**
 * @Description 开发团队的管理,添加、删除

 * @author admin
 *
 */

import com.athanchang.team.domain.Architect;
import com.athanchang.team.domain.Designer;
import com.athanchang.team.domain.Employee;
import com.athanchang.team.domain.Programmer;

public class TeamService {

	/*
	 * 给memberID赋值时使用
	 * 即:tid
	 */
	private static int counter = 1;
	private final int MAX_MEMBER = 5;//限制开发团队的人数
	private Programmer[] team = new Programmer[MAX_MEMBER];//保存开发团队成员
	private int total;//记录开发团队中的实际人数
	/*
	 * 构造器
	 */
	public TeamService() {
		super();
	}
	/**
	 * 获取开发团队中的所有成员
	 * ------
	 * 作用:
	 * 功能1、显示团队成员--将团队成员有几个列几个
	 * @return
	 */
	public Programmer[] getTeam() {
		/*
		 * 返回的是一个数组,且该数组并不是 这个类的属性数组
		 * 而是类中的属性数组 中的有效值(不包含null),组成的一个数组
		 * 用的是:数组的复制
		 */
		Programmer[] team = new Programmer[total];
		for(int i=0;i<team.length;i++) {
			team[i] = this.team[i];
		}
		//返回的是局部变量的这个team
		return team;
	}
	
	/**
	 * 将指定的员工添加到开发团队中
	 * @param e
	 * @throws TeamException 
	 */
	public void addMember(Employee e) throws TeamException {
		/*
		 * 不满足 所有异常的情况,就成功了
		 * 否则,不成功
		 */
		//1、成员已满,无法添加
		if(total >= MAX_MEMBER) {
			throw new TeamException("成员已满,无法添加");
		}
		//2、不是程序员,无法添加
		/*
		 * e instanceof Programmer:
		 * e 是 Programmer 类,或者其子类的对象实例
		 */
		if(!(e instanceof Programmer)) {
			throw new TeamException("该成员不是程序员,无法添加");
		}
		//3、该员工已在本开发团队中
		/*
		 * 做一个遍历
		 * 写一个方法来实现
		 */
		if(isExit(e)) {
			throw new TeamException("该成员已在本开发团队中");
		}
		//4、该成员已是某团队成员
		//5、该成员正在休假,无法添加
		/*
		 * 因为employee中没有status属性
		 * 但是能走到这里的一定时programmer类或者其子类的对象
		 * 而programmer中是有status属性的
		 * ------进行强转
		 */
		//这里不可以是用多态实现,因为是父类向子类转;只有子类向父类转可以用多态
		Programmer p= (Programmer)e;//一定不会出现ClassCastException,类型转换异常
		//这样更好一些:降低了空指针异常的风险
		if("BUSY".equalsIgnoreCase(p.getStatus().getNAME())) {
//		if(p.getStatus().getNAME().equals("BUSY")){
			//因为NAME是string类型的
			throw new TeamException("该成员已是某开发团队的成员"); 
		}else if("VOCATION".equalsIgnoreCase(p.getStatus().getNAME())) {
			throw new TeamException("该成员正在休假,无法添加");
		}
		
		
		//6、团队中至多只能有一名构架师	
		//7、团队中之多只能有两名设计师
		//8、团队中最多只能有三名程序员
		//获取team中已有的成员中架构师、设计师、程序员的个数
		int numOfAch = 0,numOfDes = 0,numOfPro = 0;
		for(int i=0;i<total;i++) {
			/**
			 * 注意:这里是一个重点,自己没有想到可以用instanceof来进行判断
			 * 从小到大的范围比较
			 */
			if(team[i] instanceof Architect) {
				numOfAch++;
			}else if(team[i] instanceof Designer) {
				numOfDes++;
			}else {
				numOfPro++;
			}
		}
		//
		if(p instanceof Architect) {
			if(numOfAch >= 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("团队中至多只能有三名程序员"); 
			}
		}
		/*
		 * 注意:
		 * 如果这里将每个if的嵌套的条件重叠在一起,是不可以的;
		 * 例如:
		 * 在现有的语句下,是说:是--架构师,只要不满足:架构师的数目>=1,就可以添加进去
		 * 但是,修改时候的是:
		 * 如果是架构师,且:架构师的数目>=1,
		 * 不一定 可以将该成员添加进去 --该开发团队中去
		 * 也可能会 由于满足 第二个或者第三个条件,而不能添加进去,而是直接抛出异常
		 * 是因为,在这里,三个if语句是直接并列的,
		 * -----------
		 * 但是在原来的if-else语句中:
		 * 一旦进入了是架构师的模块,就不可能再进入下面的模块
		 * ----->所以,修改前后的情况,实际上是不一样的
		 */
		//一个团队中,现在只有两个设计师。现在来一个新的员工,恰好是架构师,按照正常的逻辑来讲,是可以添加进去的
		//但是,在修改之后(错误的)逻辑中,第一个if语句没有进去,但是判断第二个语句的时候,p instanceof designer也是true,
		//所以,进入到这个if语句的语句体中去了--抛出异常“团队中至多有两名设计师”
		//不能添加进去这个  架构师
		/**
		 * 以下两个步骤的先后顺序不影响
		 */
		//将p 添加到现有的team中
		team[total++] = p;
		//开发团队中额属性赋值
		p.setStatus(Status.BUSY);
		p.setMemberId(counter++);
		
	}
	
	/**
	 * 
	 * 判断是定的员工是否已经存在于开发团队中
	 */
	private boolean isExit(Employee e) {
		
		for(int i=0;i<total;i++) {
			if(team[i].getId() == e.getId()) {
				return true;
			}
		}
		return false;
		/*
		 * 注意:e 可以走到这一步,那一定是 programmer类或者其子类的对象
		 * ----一定有memberID的属性
		 * 因为memberID的属性是在programmer类中定义的
		 * 
		 * ------所以在这里拿memberID去比较也可以,但是要把e 强转成programmer才可以去比较
		 * 而且这里的强转一定可以实现
		 * 因为能走到这里就意味着,一定是一个programmer类或者其子类
		 * --这里在进入之前,没有进入开发团队过,memberID没有赋过值,用的是默认初始化值---->0
		 * 此时进去判断,团队中的成员的就不会有谁的 memberID跟他的一样,
		 * 因为开发团队中的 成员的memberID最少也是从1 开始往后去算
		 * 如果某个员工之前加入开发团队过,假设第一次添加是3,它的后边还有4,把3这个员工移除
		 * --移除以后,可以考虑:将3的memberID不去改,但是它的状态是 free,
		 * 这时候可将3 的memberID 置为0;;或者不置为0 ,认仍旧是3
		 * 要再次把 3 添加进去,因为后边有一个4,添加成功的话,就是5,因为 开发团队中相当于就没有3的这个数据了
		 * 这个时候,再次判断 开发团队中有没有3,其实这时候里边就没有3了
		 * ------>没有3就可以添加成功了,只是把 这个3 重新赋一个值,就是5了,
		 * ----------->用memberID来判断也行,就是很麻烦
		 */
	}
	
	/**
	 * 从团队中删除成员
	 * ----对应功能3的删除成员功能(memberID)
	 * 异常:找不到指定的员工
	 * @param memberId
	 * @throws TeamException 
	 */
	public void removeMember(int memberId) throws TeamException {
		/*
		 * 遍历现有的team,看是否存在memberID与要查找的相等  的情况
		 */
		int i=0;
		
		for(;i<total;i++) {
			if(team[i].getMemberId() == memberId) {
				/*
				 * 删除:
				 * 1、将team[]中该index对应的元素拿出来,将后边的数组元素往前挪,并把原来的位于最后的位置上的值,置为null;
				 * 2、注意的是:从team中删除的元素,只是相当于不在team[]中,但是该对象仍旧在employees[]中,
				 * 现在将对象从team[]中删除,应该对于employees[]中的该对象做以下操作:
				 * (1)将它的status改成free(与add时的操作正好相反)
				 * (2)这块对于memberID,改不改无所谓(但如果是用memberID作为是否已添加在本团队中的判断的话,还是很重要的;如果不这么用,改不改回来就无所谓)
				 * 注意:在这里,由于调用的话,传递的实参到形参,并没有重新new(实例化)一个对象,而只是将employees[]中的对象元素的地址传递了过来
				 */
				//找到了这个元素
				team[i].setStatus(Status.FREE);
				break;
			}
		}
		//未找到指定memberID的情况
		if(i == total) {
			throw new TeamException("找不到指定的memberId的员工");
		}
		
		//找到了这个元素
		//后边的元素覆盖前一个元素,实现删除操作
		for(int j=i+1;j<total;j++) {
			team[j-1] = team[j];
		}
		team[total-1] = null;//将remove之前的最后一个元素置为null
		total--;//team[]减少一个元素
		
		
		
	}
	
	
}
/*
*总结:
*1、instanceof:
*(自己迷糊了好久)只需记住一句话
* a instanceof A,那么,a所属的类 与 A类,必须是子类和父类的关系
*/

3、Status类

/*
 * 枚举类:
 * 只有有限个,可以都枚举出来,叫做:有限个的
 * 在这个问题中,对象有3个,而且只有3个
 */
public class Status {

	//属性
	private final String NAME;
	//类的构造器要私有化------不允许在外边造对象了
	private Status(String name) {
		this.NAME = name;
	}
	
	/*
	 * 造3个对象,这3个对象(也可以叫做3个变量)可以直接通过类去调用
	 * ------声明为public
	 * 值不可以修改
	 * -----final
	 * 常量
	 * -----static
	 */
	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 String getNAME() {
		return NAME;
	}
	
	/*
	 * 需要重写toString
	 * 因为FREE BUSY VOCATION,是三个对象的NAME属性的值
	 * 而且对象是静态的(全局常量),类似于 “单例模式”
	 * 只不过这里是三个对象而已
	 * ------那么,在重写的时候直接输出对应的 对象的 NAME 属性的值
	 * 即可
	 */
	@Override
	public String toString() {
		
		return NAME;
	}
	
}

4、TeamView类

import com.athanchang.team.domain.Employee;
import com.athanchang.team.domain.Programmer;
import com.athanchang.team.service.NameListService;
import com.athanchang.team.service.TeamException;
import com.athanchang.team.service.TeamService;

public class TeamView {

	/*
	 * 属性:实际上是NameListService类、类的对象
	 */
	private NameListService listSvc = new NameListService();
	private TeamService teamSvc = new TeamService();

	public void enterMainMenu() {

		/*
		 * 将整个界面的逻辑放入一个循环中去 可以实现:菜单栏的重复选择和使用
		 */
		// while的终止条件
		boolean loopFlag = true;
		char menu = 0;
		while (loopFlag) {
			/*
			 * 保证,只有输入的不是‘1’的情况下,才会在执行操作之后再次输出公司员工列表
			 */
			if (menu != '1') {
				listAllEmployees();
			}

			System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):");
			/*
			 * 输入
			 */
			menu = TSUtillity.readMenuSelection();
			switch (menu) {
			case '1':// 团队列表
				getTeam();
				break;
			case '2':// 添加团队成员
				addMember();
				break;
			case '3':// 删除团队成员
				deleteMember();
				break;
			case '4':// 退出功能
				System.out.println("确认是否退出(Y/N):");
				char isExit = TSUtillity.readConfirmSelection();
				/*
				 * 因为TSUtillity.readConfirmSelection()中, 使用了readKeyBoard(1,false).toUpperCase();
				 * 将从键盘读入的数据统统转换为大写
				 */
				if (isExit == 'Y') {
					loopFlag = false;
				}
				/*
				 * 结束switch
				 */
				break;
			}
		}

	}

	/**
	 * 显示所有的员工信息
	 */
	private void listAllEmployees() {

		System.out.println("-----------------------------开发团队调度软件---------------------------\n");
		/*
		 * 公司的员工,这个 对象数组 不可能为空,所以可以不进行判空的判断
		 */
//		System.out.println("");
		Employee[] employees = listSvc.getAllEmployees();
		if (employees.length == 0) {
			// 公司员工数为0
			/*
			 * 注意:这儿里有一个坑: 有时候对于判断一个对象数组是否存有数据,应该将判断条件写为: employees == null ||
			 * employees.length == 0 这是因为:
			 * ①如果返回的是一个已经实例化过(new过的)数组,且数组为空的话,可以直接用employees.length == 0来判断
			 * ②如果返回的是一个没有实例化过的数组(仅仅声明了变量,但是没有new过),判断数组为空的话,应该用employees ==null来进行判断
			 * 此时,employees是null的话,employees.length,就是空指针了
			 */
			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");
	}

	private void getTeam() {

		System.out.println("-------------------团队成员列表------------------");

		Programmer[] team = teamSvc.getTeam();
		// 因为team[]已经new过了,所以肯定不是一个null
		if (team.length == 0) {
			System.out.println("开发团队目前没有成员!");
		} else {
			// 找到team[]
			System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t奖金\t股票\n");
			for (int i = 0; i < team.length; i++) {
				/*
				 * 因为前边的重写过的toString()跟这里的要求不匹配, 所以不能在这里只是简单地调用team[i]的toString()
				 * ------在programer的类中写一个方法,帮助这的输出格式匹配 之所以在programer中写,是因为:
				 * ①designer、architect都是programmer的子类,可以继承(重写)programmer的方法
				 * ②根据TeamViewer中的addMember,发现最少是程序员才可以加入开发团队,所以写在employee类中的话,对employee类的对象而言,
				 * 没有意义
				 * 
				 */
				System.out.println(team[i].getDetailsForTeam());
				// 此时,调用getTeamBaseDetails()这个方法,就看team[i]具体是谁了,是谁就调用谁的对象
				// ----即,getTeamBaseDetails()调用的是哪个类中的对应的方法,就看具体是哪个类的实例化对象了
				// 因为programmer、designer、architect类中,均有该方法或是 对于该方法的重写
			}
		}
		System.out.println("----------------------------------------------");
	}

	private void addMember() {

		System.out.println("--------------------------添加团队成员-------------------------");
		System.out.print("请输入要添加的员工的ID:");
		// 从键盘读入要添加的成员的ID
		int id = TSUtillity.readInt();
		/*
		 * 通过id找到指定未知的员工,从而才可以将该员工 尝试 加入 开发团队中
		 * 
		 */
		try {
			/*
			 * 在这里的异常该处理了,因为这里就是最红的调用了
			 */
			Employee emp = listSvc.getEmployee(id);
			// getEmployee(int id)中,可以判断id 对应的员工 是否可以找到
			teamSvc.addMember(emp);
			// addMember(emp)可能添加不成功------不符合对于:向开发团队添加员工的要求
			System.out.println("添加成功!");

		} catch (TeamException e) {
			// TODO Auto-generated catch block
			System.out.println("添加失败,原因:" + e.getMessage());

		}
		// 按回车键继续
		TSUtillity.readReturn();
		/**
		 * 详细的分析可以看TSU illity.readReturn();这块的文档注释
		 */

	}

	private void deleteMember() {

		System.out.println("--------------------------删除团队成员-------------------------");

		/*
		 * 开发团队中,有成员存在的情况下,才可以从开发团队中删除成员
		 */
		Programmer[] team = teamSvc.getTeam();
		// 因为team[]已经new过了,所以肯定不是一个null
		if (team.length == 0) {
			System.out.println("开发团队目前没有成员!");
		} else {
			System.out.print("请输入要添加的员工的TID:");
			/*
			 * 需注意的是:这里是按照TID,即,memberID进行删除 在employee、programmer、designer、architect几个类中,
			 * 在employee中,定义了属性id;在programmer中,定义了属性memberId;
			 * 
			 */
			int memberId = TSUtillity.readInt();

			System.out.println("确认是否删除(Y/N)");
			char isDelete = TSUtillity.readConfirmSelection();
			// 并不是真的删除
			if (isDelete == 'N') {
				return;
			}
			// 走到这,说明是:真想删
			try {
				teamSvc.removeMember(memberId);
				// 删除成功
				System.out.println("删除成功");
			} catch (TeamException e) {
				// TODO Auto-generated catch block
				System.out.println("删除失败,原因:" + e.getMessage());
			}
			// 按回车键继续
			TSUtillity.readReturn();
			/**
			 * 详细的分析可以看TSU illity.readReturn();这块的文档注释
			 */

		}

	}

	public static void main(String[] args) {
		/*
		 * 造一个当前类的对象,然后通过对象调用enterMainMenu 显示主要的界面 ----主要的功能在enterMainMenu中完成
		 */
		TeamView view = new TeamView();
		view.enterMainMenu();

	}

}

完整源码

完整的代码放在下面的位置:
源码地址
点开不必VIP,关注即可下载。

行百里者,半九十。加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值