JAVA 编程练习0_5------------开发团队调度软件

项目需求分析

  1. 根据给定的数据创建公司部分员工列表;
  2. 基于现有的公司成员,组建一个开发团队;
  3. 展示出开发团队成员有哪些,并实现增加、删除操作;
  4. 开发团队的任职各有不同。

如果添加操作失败,则需要提示信息:
失败信息包含以下几种:
– 成员已满,无法添加
– 该成员不是开发人员,无法添加
– 该成员已在本开发团队中
– 该员工已是某团队成员
– 该成员正在休假,无法添加
– 团队中至多只能由一名架构师
– 团队中至多只能由两名设计师
– 团队中至多只能由三名程序员

软件设计结构

在这里插入图片描述

  1. TeamView 主控模块,负责菜单的显示和处理用户操作
  2. service(图中间三个大类)为实体对象(Employee及其子类)的管理模块,NameListService和TeamService类分别用各自的数组来管理公司员工和开发团队成员对象
  3. Employee类中还有程序员、设计师、架构师等子类。

工具类代码块

TSUtility类的解释:通过调用此类,可以实现键盘的访问。该类提供了以下静态方法
public static char readMenuSelection()
用途:该方法读取键盘,如果用户键入’1’-‘4’中任意字符,则方法返回。返回值为用户键入字符
public static void readReturn()
用途:该方法提示并等待,直到用户按回车键结束后返回。
public static int readInt()
用途:该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
public static char readConfirmSelection()
用途:从键盘读取’Y’或’N’。并将其作为方法的返回值。

package item_3_sgg;
import java.util.*;
/*
 * @Description 项目中提供了TSUtility.java类,可用来方便地实现键盘访问。
 */
public class TSUtility {
	private static Scanner scanner =new Scanner(System.in);
	/*
	 * @Description 该方法读取键盘,如果用户键入'1'-'4'中任意字符,则方法返回。返回值为用户键入字符
	 */
	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 该方法提示并等待,直到用户按回车键结束后返回。
	 */
	public static void readReturn() {
		System.out.print("按回车键继续....");
		readKeyBoard(100,true);
	}
	/*
	 * @Description 该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
	 */
	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'。并将其作为方法的返回值。
	 */
	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;
	}
}

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;//PC
	public static final int NOTEBOOK=22;//笔记本
	public static final int PRINTER=23;//打印机
	
	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"},
			{"10","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","杨致远","22","9600","4800"},
	};
	
	public static final String[][] EQUIPMENTS= {
			{},
			{"22","联想T4","6000"},
			{"21","戴尔","NEC17寸"},
			{"21","戴尔","三星17寸"},
			{"23","佳能 2900","激光"},
			{"21","华硕","三星17寸"},
			{"21","华硕","三星17寸"},
			{"23","爱普生20K","针式"},
			{"22","惠普m6","5800"},
			{"21","戴尔","NFC 17寸"},
			{"21","华硕","三星17寸"},
			{"21","惠普m6","5800"},	
	};
}

设备类 Equipment代码块

通过重写接口的抽象方法,使得每个具体的设备类显示不同数据。

public interface Equipment {
	public abstract String getDescription();
}

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;
	}

	public String getDescription() {
		return model + "("+price+")";
	}
}
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;
	}
	public String getDescription() {
		
		return model + "("+display+")";
	} 
}
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;
	}
	public String getDescription() {
		return name +"("+type+")";
	}
}

员工类 Employee代码块

注意:需要重写toString方法,返回相应的数据。可以在超类里写一个getDetails()方法来满足后续子类需要调用基本数据的需求。对所有属性需要进行封装,再有set(),get()方法来赋值或者调用。具体在员工类当中有Programmer、Designer、Architect

//超类员工类
public class Employee {
	private int id;
	private String name;
	private int age;
	private double 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 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 String getDetails() {
		return id+"\t"+name+"\t"+age+"\t"+salary;
	}
	@Override
	public String toString() {
		return getDetails();     
	}
}
//父类,程序员类
class Programmer extends Employee {
	private int memberId;//开发团队ID
	private Status status=Status.FREE;//所有人员的初始状态都是FREE
	private 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;
	}
	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 getDetails()+"\t程序员\t"+status+"\t\t\t"+equipment.getDescription();
	}
	public String getdetDetailsForTeam(){
		return memberId+"/"+getId()+"\t"+getName()+"\t"+getAge()+"\t"+getSalary()+"\t程序员";
	}
	
}
//子类:设计师类(继承程序员)
class Designer extends Programmer{
	private double 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;
	}

	public double getBonus() {
		return bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}
	@Override
	public String toString() {
		
		return getDetails()+"\t设计师\t"+getStatus()+"\t"+bonus+"\t\t"+getEquipment().getDescription();
	}
	public String getdetDetailsForTeam(){
		return getMemberId()+"/"+getId()+"\t"+getName()+"\t"+getAge()+"\t"+getSalary()+"\t设计师\t"+getBonus();
	}
}
//子类:架构师类(继承设计师)
class Architect extends Designer{
	 private int 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;
	}

	public int getStock() {
		return stock;
	}

	public void setStock(int stock) {
		this.stock = stock;
	}	
	@Override
	public String toString() {
		
		return getDetails()+"\t架构师\t"+getStatus()+"\t"+getBonus()+"\t"+stock+"\t"+getEquipment().getDescription();
	}
	public String getdetDetailsForTeam(){
		return getMemberId()+"/"+getId()+"\t"+getName()+"\t"+getAge()+"\t"+getSalary()+"\t架构师\t"+getBonus()+"\t"+getStock();
	}
}

Status代码块

用来表示员工的状态
分为FREE\BUSY\VOCATION三种状态,主要利用枚举的知识点
重写toString()方法来获得NAME

/*
 * 表示员工的状态
 */
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 BUSY= new Status("BUSY");
	public static final Status VOCATION= new Status("VOCATION");
	public String getNAME() {
		return NAME;
	}
	@Override
	public String toString() {
		return NAME;
	}
}

NameListService代码块

负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]方法。
1.根据项目提供的Data类构建相应大小的employees数组
2.再根据Data类中的数据构建不同的对象,包括Employee、Programmer、Designer和Architect对象、以及相关联的Equipment子类的对象
3.将对象存于数组中

/*
 * 负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]方法。
 */
import static item_3_sgg.Data.*;
public class NameListService {
	private Employee[] employees;
	/*
	 * 给employee及数组元素进行初始化
	 */
	public NameListService() {
//		1.根据项目提供的Data类构建相应大小的employees数组
//		2.再根据Data类中的数据构建不同的对象,包括Employee、Programmer、Designer和Architect对象、以及相关联的Equipment子类的对象
//		3.将对象存于数组中
		
		employees =new Employee[EMPLOYEES.length];//EMPLOYEES.length已经由Data提供
		
		for(int i=0;i<employees.length;i++) {
			//获取员工的类型
				int type = Integer.parseInt(EMPLOYEES[i][0]);
				
				//获取Employee的4个基本信息
				int id=Integer.parseInt(EMPLOYEES[i][1]);
				String name=EMPLOYEES[i][2];
				int age=Integer.parseInt(EMPLOYEES[i][3]);
				double salary =Double.parseDouble(EMPLOYEES[i][4]);
				
				Equipment equipment;
				double bonus;
				int stock;
				switch(type){
				case EMPLOYEE:
					employees[i]=new Employee(id,name,age,salary);
					break;
				case PROGRAMMER:
					equipment= createEquipment(i);
					employees[i]=new Programmer(id,name,age,salary,equipment);
					break;
				case DESIGNER:
					equipment=createEquipment(i);
					bonus=Double.parseDouble(EMPLOYEES[i][5]);
					employees[i]=new Designer(id,name,age,salary,equipment,bonus);
					break;
				case ARCHITECT:
					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);
					break;
				}		
		}
	}
	//获取指定index上的员工的设备
	private Equipment createEquipment(int index) {
		int type=Integer.parseInt(EQUIPMENTS[index][0]);
		switch(type) {
		case PC://21
			return new PC(EQUIPMENTS[index][1],EQUIPMENTS[index][2]);
		case NOTEBOOK://22
			String model =EQUIPMENTS[index][1];
			double price =Double.parseDouble(EQUIPMENTS[index][2]);
			return new NoteBook(model,price);
		case PRINTER://23
			return new Printer(EQUIPMENTS[index][1],EQUIPMENTS[index][2]);
		}
		return null;
	}
	//获取当前所有员工
	public Employee[] getALLemployees() {
		return employees;
	}	
	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 ("找不到指定的员工");
	}
}

TeamService代码块

关于开发团队成员的管理:添加、删除等。
1.添加方法public void addMember(Employee e) throws TeamException {}
如果成员已满,不是开发人员,已在本开发团队或者状态不是FREE就都不能进行添加,所以此时都需要抛出异常。
2.删除方法public void removeMember(int memberId) throws TeamException {}
找不到指定的memberId的员工就无法删除,需要抛出异常。
需要将被删除的成员状态改为FREE,后面的元素覆盖前一个元素,实现删除。

//关于开发团队成员的管理:添加、删除等。
public class TeamService {
	private static int counter =1;//给memberId赋值使用
	private final int MAX_MEMBER =5;//限制开发团队的人数
	private Programmer[] team=new Programmer[MAX_MEMBER];//保存开发团队成员
	private int total;//记录开发团队中实际的人数
	public TeamService() {
		super();
	}
	
	//得到开发团队成员
	public Programmer[] getTeam() {
		Programmer[] team=new Programmer[total];
		for(int i=0;i<team.length;i++) {
			team[i]=this.team[i];
		}
		return team;
	}
	//将指定员工增加到开发团队
	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".equals(p.getStatus().getNAME())) {
			 throw new TeamException("该员正在休假,无法调用");
		 }
		 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.setStatus(Status.BUSY);
		 p.setMemberId(counter++);
		 team[total++]=p;
	}
	private boolean isExist (Employee e) {
		for(int i=0;i<total;i++) {
			if(team[i].getId()==e.getId()) {
				return true;
			}
		}
		return false;
	}
	public void removeMember(int memberId) throws TeamException {
		int i;
		for(i=0;i<total;i++) {
			if(team[i].getMemberId()==memberId) {
				team[i].setStatus(Status.FREE);
				break;
			}
		}
		if(i==total) {
			throw new TeamException("找不到指定的memberId的员工,删除失败");
		}
		//后面的元素覆盖前一个元素,实现删除
		for(int j=i;j<total-1;j++) {
			team[j]=team[j+1];
		}
		team[--total]=null;
	}
}

TeamException代码块

用户自定义的异常类,编译时有问题就抛出异常。

public class TeamException extends Exception{
	static final long serialVersionUID = -33875124229948L;
	public TeamException() {
		super();
	}
	public TeamException(String msg) {
		super(msg);
	}
}

TeamView代码块

主要模块,用户操作和交互都在这里进行实现

public class TeamView {

	private NameListService listSvc =new NameListService();//负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]方法。
	private TeamService teamSvc = new TeamService();//关于开发团队成员的管理:添加、删除等。
	private Programmer[] team;
	
	public void enterMainMenu() {
		boolean loopFlag=true;
		char menu=0;
		
	while(loopFlag) {
		if(menu !='1') {
		listAllEmployees();
		}
		
		System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):");
		menu=TSUtility.readMenuSelection();
		switch(menu) {
		case '1':
			getTeam();
			break;
		case '2':
			addMember();
			break;
		case '3':
			deleteMember();
			break;
		case '4':
			System.out.print("确定是否退出(Y/N)");
			char isExit =TSUtility.readConfirmSelection();
			if(isExit=='Y') {
				loopFlag=false;
			}
			break;
			
		}
	}
	}
	private void listAllEmployees() {
		System.out.println("----------------------------------------开发团队调度软件----------------------------------------");
		Employee[] employees=listSvc.getALLemployees();
		if(employees==null||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("---------------------------------------------------------------------------------------------");
	}
	private void getTeam() {
		System.out.print("-------------------------团队成员列表-------------------------\n");
		Programmer[] team = teamSvc.getTeam();
		if(team==null||team.length==0)
		{
			System.out.println("开发团队目前没有成员!");
		}else{
			System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t奖金\t股票\n");
			for(int i=0;i<team.length;i++)
			{
				System.out.println(team[i].getdetDetailsForTeam());
			}
		}
		
	}
	private void addMember() {
		System.out.print("-------------------------添加团队成员-------------------------\n");
		System.out.print("请输入要添加的员工ID:");
		int id=TSUtility.readInt();
		try {
		Employee emp=listSvc.getEmployee(id);
		teamSvc.addMember(emp);
		System.out.println("添加成功");
		}catch(TeamException e) {
			System.out.println("添加失败,原因:"+e.getMessage());
		}
		TSUtility.readReturn();
	}
	private void deleteMember() {
		System.out.print("-------------------------删除团队成员-------------------------\n");
		System.out.print("请输入要删除的员工TID:");
		int memberId=TSUtility.readInt();
		System.out.print("确认是否要删除(Y/N):");
		char isDelete =TSUtility.readConfirmSelection();
		if(isDelete=='N') {
			return;
		}
		try {
			teamSvc.removeMember(memberId);
			System.out.println("删除成功");
		}catch(TeamException e) {
			System.out.println("删除失败,原因:"+e.getMessage());
		}
		TSUtility.readReturn();
	}
	public static void main(String[] args) {
		TeamView view =new TeamView();
		view.enterMainMenu();
		
	}
}

总结

完成这个项目耗费时间较长,但涵盖了之前所学Java面向对象的所有知识点,让我加固了面向对象的知识点。
设计此类系统的思路呈现:
1.工具类(TSUtility、Data)的设计
1)考虑所需功能有几个,读取键盘上功能的序列号,然后返回这个序列号
2)确认是否要进行操作,通过‘Y’&&‘N’(用toUpperCase()方法可以转化成大写)
3)根据用户输入,读取键盘上的数字
从键盘输入方法:

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;
	}

2.考虑人员共有属性为父类,然后根据具体情况,可以写新的子类创建特性。
3.将已知信息或者输入的Data存放到人员类的数组里面,并且考虑操作这个数组。
4.考虑实现具体功能的方法(增加,删除,查找,修改)。
5.考虑界面实现以及用户交互。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值