【超棒的小项目】Java SE巩固项目--- 团队调度软件(继承,多态,多种基础知识综合应用,学会宏观思考)!!

Java SE项目收尾

内容导航

    • 开发之前的话
    • 开发团队调度软件【项目】
      • 项目涉及知识点
      • 项目需求
      • 项目架构
      • 项目问题
        • 项目报错 抛出异常because "this.ept" is null
        • 项目报错 超出范围
        • 项目输出结果 不规范
    • 项目源码(部分)注解详细
    • view包主界面
      • Swevice包
        • NameList类
        • TeamListService类
        • Date类(数据来源)
      • Datafield包
        • Programmer类

Java养成计划


java se 项目 --- 开发团队调度软件【基于文本界面】

看一下效果
【超棒的小项目】Java SE巩固项目--- 团队调度软件(继承,多态,多种基础知识综合应用,学会宏观思考)!!_第1张图片
添加后公司成员状态
【超棒的小项目】Java SE巩固项目--- 团队调度软件(继承,多态,多种基础知识综合应用,学会宏观思考)!!_第2张图片

开发之前的话

至于为什么要写这个项目,或者说为什么要实现这个项目,是因为之前的socket聊天室项目虽然复杂,但说实话真的不复杂,大部分代码都是在进行界面设计,核心就是TCP/IP通信,再加上线程使用就没有了,简化版就可以看出来,仅仅70行就可以实现核心的文本聊天功能

所以,不管是读者或者是我本身都觉得JAVA SE以这个项目收官不具有代表性,所以接,下来将用时间来实现这个开发团队调度软件,架构使用的MVC设计模式

开发团队调度软件【项目】

项目涉及知识点

本项目涉及的知识点: 类的继承性和多态性,对象的值传递、接口,static和final修饰符,特殊类的使用:包装类、抽象类、内部类,异常处理(开发)–不是简单的try-catch,throws

本项目架构主要依据的是MVC设计模式

所谓MVC设计模式就是将项目分层

【超棒的小项目】Java SE巩固项目--- 团队调度软件(继承,多态,多种基础知识综合应用,学会宏观思考)!!_第3张图片

项目需求

  • 软件启动时,根据给定数据创建公司部分成员列表

  • 根据菜单提示,基于现有的公司成员,组件一个开发团队

  • 组件过程包括将成员插入到团队当中,或者从团队中删除某位成员,还可以列出团队中现有成员的列表

  • 开发人员包括架构师、设计师和程序员

项目架构

本项目使用MVC设计模式,将整个项目分为3个包

  • pers.Cfeng.groupsheduing.view

很显然,这个包的作用就是实现组织调度软件的视图功能,就是向用户显示界面,这里我们为了方便代码的写作速度,就先不引入java web或者界面GUI了,就使用控制台展示

  • pers.Cfeng.groupsheduing.service

这个包的作用就是提供服务的

  • pers.Cfeng.groupsheduing.datafiled

这个包是包含软件所操作的对象,这里就是公司的职员

【超棒的小项目】Java SE巩固项目--- 团队调度软件(继承,多态,多种基础知识综合应用,学会宏观思考)!!_第4张图片

项目问题

项目报错 抛出异常because “this.ept” is null

经过Debug发现是在选择设备的方法中将EQUIPMENT写成了EMPLOYEE, 修改后正常

项目报错 超出范围

发现是因为设备组和成员组的数量不一致,导致最后一个成员对应的是空内存,加上一个{}解决

项目输出结果 不规范

成员列表时,没有Programmer列没有对齐,进入类中修改后正常

项目源码(部分)注解详细

view包主界面

package pers.Cfeng.groupsheduing.view;
/**
 * @author Cfeng
 *本类为应用程序起始主类,并实现控制台界面的展示
 */

import pers.Cfeng.groupsheduing.datafield.*;
import pers.Cfeng.groupsheduing.service.*;

public class TeamView {
     
	private NameListService listService = new NameListService();
	private TeamListService teamService = new TeamListService();
	//定义选择的数字对应的操作
	private static final char TEAMLIST = '1';
	private static final char ADDMEMBER = '2';
	private static final char DELMEMBER = '3';
	private static final char EXIT = '4';
	//进入主菜单; 
	public  void enterMainMenu() {
     
		boolean loopFlag = true; //退出操作的
		char key = 0;
		//先输入,再执行,所以为do-while循环
		do {
     
			if(key != '1') {
     
				listAllEmployees();//显示公司所有成员
			}
			System.out.print("1-团队列表  2-添加成员 3-删除团队成员 4-退出 请选择(1-4):");
			key = UtilView.readMenuSelection();
			System.out.println();
			switch(key){
     
				case TEAMLIST:
					listTeam();
					break;
				case ADDMEMBER:
					addMember();
					break;
				case DELMEMBER:
					delMember();
					break;
				case EXIT:
					System.out.print("确认是否退出(Y/N)");
					char confirm = UtilView.readConfirmSelection();
					if(confirm == 'Y')
						loopFlag = false;
					break;
			}
		}while(loopFlag);//语句结束
	}
	
	//显示
	private void listAllEmployees() {
     
		System.out.print("\n***************************团队调度软件模拟******************************************\n");
		System.out.print("--welcome------------------------W市CT科技公司--------welcome--------------------------\n");
		Employee[] tempe = listService.getAllEmployees();
		if(tempe.length == 0) {
     
			System.out.println("没有客户记录!");
		}
		else
			System.out.println("ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t使用设备");
		for(Employee em : tempe) {
     
			System.out.println(" " + em);
		}
		System.out.print("--welcome-----------------W市CT科技公司--------welcome---------------------------------\n");
	}
	//团队成员列表
	private void listTeam() {
     
		System.out.print("--hello-----------------CT科技CT项目组--------hello---------------\n");
		Programmer[] team = teamService.getTeam();
		if(team.length == 0) {
     
			System.out.println("该项目组中还没有开发成员!");
		}
		else
			System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t奖金\t股票");
		
		for(Programmer pr : team) {
     
			System.out.println(" " + pr.toString());
		}
		System.out.print("--hello-----------------CT科技CT项目组--------hello---------------\n");
	}
	//添加成员到团队
	private void addMember() {
     
		System.out.println("-----------------------添加成员到项目组----------------------");
		System.out.println("请输入要添加的员工ID :");
		int id = UtilView.readInt();
		
		try {
     
			Employee e = listService.getEmployee(id);
			teamService.addMember(e);
			System.out.println("添加成功");
		}catch(TeamException e) {
     
			System.out.println("添加失败,"+ e.getMessage());
		}
		//按回车继续
		UtilView.readReturn();
	}
	//删除成员
	private void delMember() {
     
		System.out.println("-----------------------删除项目组成员----------------------");
		System.out.println("请输入要删除的员工TID:");
		int id = UtilView.readInt();
		System.out.print("是否确认删除(Y/N)");
		char confirm = UtilView.readConfirmSelection();
		if(confirm == 'N')
			return;
		try {
     
			teamService.DelMember(id);
			System.out.println("删除成功");
		}catch(TeamException e) {
     
			System.out.println("删除失败," + e.getMessage());
		}
		UtilView.readReturn();//回车继续
	}
	
	//起始类
	public static void main(String[] args) {
     
		TeamView view = new TeamView();
		view.enterMainMenu();
	}
}

Swevice包

NameList类

package pers.Cfeng.groupsheduing.service;

/**
 * @author Cfeng
 *将用户写成列表的形式
 */
import pers.Cfeng.groupsheduing.datafield.*;
import static pers.Cfeng.groupsheduing.service.Data.*;//导入数据

public class NameListService {
     //单击加F2一键修改类名,包名
	private Employee[] employees;//导入的职工数据存储
	//构造方法将数据导入
	public NameListService() {
     //数组的复制
		//将data中的String类型转化为相应类型
		employees = new Employee[EMPLOYEES.length];//分配内存
		for(int i = 0; i < employees.length; i++)
		{
     
			int type = Integer.parseInt(EMPLOYEES[i][0]);
			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 ept;
			double bonus;
			int stock;
			//根据类型选择合适的身份;用常量代替数字,更加合适
			switch(type)
			{
     
				case EMPLOYEE:{
     
					employees[i] = new Employee(id, name, age, salary);
					break;
				}
				case PROGRAMMER:{
     
					ept = createEquiment(i);//与位置是对应的
					employees[i] = new Programmer(id, name, age, salary, ept);
					break;
				}
				case DESIGNER:{
     
					ept = createEquiment(i);
					bonus = Double.parseDouble(EMPLOYEES[i][5]);
					employees[i] = new Designer(id, name, age, salary, ept, bonus);
					break;
				}
				case ARCHITECT:{
     
					ept = createEquiment(i);//这里最开始报错越界,修改后正常
					bonus = Double.parseDouble(EMPLOYEES[i][5]);
					stock = Integer.parseInt(EMPLOYEES[i][6]);
					employees[i] = new Architect(id, name, age, salary, ept, bonus, stock);
				    break;
				}
			
			}
		}
	}
	private Equipment createEquiment(int index) {
     
		int type = Integer.parseInt(EQUIPMENTS[index][0]);//之前这里写成了EMPLOYEE,就置空了
		switch(type)
		{
     
			case PC:
				return new PC(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
			case NOTEBOOK:
				return new NoteBook(EQUIPMENTS[index][1], Integer.parseInt(EQUIPMENTS[index][2]));
			case PRINTER:
				return new Printer(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
		}
		return null;
	}
	
	//定义操纵数组的方法
	public Employee[] getAllEmployees() {
     
		return employees;
	}
	
	public Employee getEmployee(int id) throws TeamException {
     
		for(Employee t: employees)
		{
     
			if(t.getId() == id)
			{
     
				return t;
			}
		}//自定义抛出异常
		throw new TeamException("该员工不存在");
	}
}
/*
	//测试一下
	public static void main(String[] args) throws TeamException {//抛出异常because "this.ept" is null
		for(int i = 1;i <= 13;i++)
		{
			Employee test = new NameListService().getEmployee(i);
			System.out.println(test.toString());
		}
	}
	
}	
*/

TeamListService类

package pers.Cfeng.groupsheduing.service;
/**
 * @author Cfeng
 *本类为操作将公司职员加入到工作团队中
 *因为为开发团队,所以就不包括普通的职员
 */

import pers.Cfeng.groupsheduing.datafield.*;

public class TeamListService {
     
	private int total = 0;//成员总数
	private final int MAX_MENMBER = 5;//团队最大人数
	private int counter = 1;//计数团队成员
	private Programmer[] team = new Programmer[MAX_MENMBER];
	
	public TeamListService() {
     
		//
	}
	//get方法,数组类型也是对象类型;返回团队数组
	public Programmer[] getTeam() {
     
		Programmer[] team = new Programmer[total];
		for(int i = 0;i < total;i++)
		{
     
			team[i] = this.team[i];//复制输出
		}
		return team;
	}
	//向团队中增加人员
	public void addMember(Employee per) throws TeamException {
     
		if(total >= MAX_MENMBER) throw new TeamException("成员已满,无法添加");
		//使用instanceof判断是否为Programmer对象(包括子类)
		if(!(per instanceof Programmer)) throw new TeamException("该成员不是开发人员,重新选择");
		//是Programmer,强制类型转换
	    //使用子类的特有方法,转型
		Programmer programmer = (Programmer)per;
		if(isExit(programmer)) throw new TeamException("该成员已在团队中");
		if(programmer.getStatu().getStatu().equals("BUSY")) throw new TeamException("该成员已经在团队中");
		if(programmer.getStatu().getStatu().equals("VOCATION")) throw new TeamException("该成员在度假中");
		
		//团队最多一名架构师,两名设计师和三名程序员
		int numOfArch = 0, numOfDsgn = 0, numOfPrg = 0;
		for(int i = 0; i < total; i++) {
     
			if(team[i] instanceof Architect) {
     
				numOfArch ++;
			}
			else if(team[i] instanceof Designer) {
     
				numOfDsgn++;
			}
			else {
     
				numOfPrg++;
			}
		}
		//判断是否超出人数要求
		 if (programmer instanceof Architect) {
     
	            if (numOfArch >= 1) throw new TeamException("团队中至多只能有一名架构师");
	        } else if (programmer instanceof Designer) {
     
	            if (numOfDsgn >= 2) throw new TeamException("团队中至多只能有两名设计师");
	        } else if (programmer instanceof Programmer) {
     
	            if (numOfPrg >= 3) throw new TeamException("团队中至多只能有三名程序员");
	        }
		 //没有异常,继续正常添加
		 programmer.setStatu(Status.BUSY);//设置状态
		 programmer.setMemberId(counter++);
		 team[total++] = programmer;
	}
	
	private boolean isExit(Programmer p) {
     
		for(int i = 0; i < total; i++) {
     
			if(team[i].getId() == p.getId()) {
     
				return true;
			}
		}
		return false;
	}
	//删除团队中的成员
	public void DelMember(int memberId) throws TeamException {
     
		int n = 0;
		for(; n < total; n++) {
     
			if(team[n].getMemberId() == memberId) {
     
				team[n].setStatu(Status.FREE);
				break;
			}
		}
		//删除就要移动后面的元素
		if(n == total) {
     
			throw new TeamException("找不到该成员,无法删除");
		}
			for(int i = n + 1; i < total; i++) {
     
				team[i - 1] = team[i];
		}
		team[--total] = null; //置空,垃圾回收线程处理,size会自动变化	
	}
}

Date类(数据来源)

package pers.Cfeng.groupsheduing.service;

/**
 * 这个包的功能是服务层,所有与服务相关的类都再里面
 * @author Cfeng
 * Data类就是数据来源以及规范,定义了数据诸如各类职工.设备编号【调用时方便】,以及使用二维数组定义了各种员工和设备的初始数据
 * Attion: 这里的数据我们要求时不可修改的,因此需要将它们定义为final类型
 * 数据的来源其实可以时文件,这里就先简单一点,直接输入
 * 
 * 该类为服务操作层的初始数据操作层
 */
public class Data {
     
	//使用编号指代各种职工,包括普通职员,设计师,程序员,架构师;注意常量定义的规范;数据在操作过程中不允许修改,访问权限设置为public,其他的类可以使用
	public static final int EMPLOYEE = 101;//101代表普通职员
	public static final int PROGRAMMER = 102; 
	public static final int DESIGNER = 103;
	public static final int  ARCHITECT = 104;
	//使用编号定义各类设备
	public static final int PC = 121;
	public static final int NOTEBOOK = 122;
	public static final int PRINTER = 123;
	/**
	 * 各种员工的属性,从上到下职级越高,福利越好
	 * Employee :   101,id,name,age,salary
	 * Programmer:  102,id,name,age,salary
	 * Designer:    103,id,name,age,salary,bonus
	 * Architect:   104,id,name,age,salary,bonus,stock
	 * 使用一个初始二维数组EMPLOYEES来写入一组初始数据,注意使用的时String类型的
	 */
	public static final String[][] EMPLOYEES = {
     //这里的排序方式是入职的早晚来的,不是职级
			{
     "101","1","C神","35","3000"},
			{
     "102","2","C云","34","3500"},
			{
     "103","3","C强","30","3800","3000"},
			{
     "102","4","李L","31","3100"},
			{
     "103", "5", "雷J", "28", "10000", "5000"},
	        {
     "102", "6", "张Q", "22", "6800"},
	        {
     "103", "7", "柳Y", "29", "10800","5200"},
	        {
     "104", "8", "C风", "30", "19800", "15000", "2500"},
	        {
     "103", "9", "C雨", "26", "9800", "5500"},
	        {
     "102", "10", "丁D", "21", "6600"},
	        {
     "102", "11", "张C", "25", "7100"},
	        {
     "103", "12", "C杨", "27", "9600", "4800"},
	        {
     "104", "13", "刘大W", "30", "19500", "17000", "3000"},
	};//定义了一个二维数组,代码太长,要分行
	/**如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应
     * PC      :121, model, display
     * NoteBook:122, model, price
    *  Printer :123, name, type 
    */
    public static final String[][] EQUIPMENTS = {
     //普通员工不需要
    	{
     },
        {
     "122", "联想T4", "6000"},
        {
     "121", "戴尔", "NEC17寸"},
        {
     "121", "戴尔", "三星 17寸"},
        {
     "123", "佳能 2900", "激光"},
        {
     "121", "华硕", "三星 17寸"},
        {
     "121", "华硕", "三星 17寸"},
        {
     "123", "爱普生20K", "针式"},
        {
     "122", "惠普m6", "5800"},
        {
     "121", "戴尔", "NEC 17寸"},
        {
     "121", "华硕","三星 17寸"},
        {
     "122", "惠普m6", "5800"},
        {
     "123", "HP M401d", "喷墨"}
    };
}

Datafield包

这里解释一下,programmer继承Employee,Designer继承Programmer,Architect继承Designer

Programmer类

package pers.Cfeng.groupsheduing.datafield;
/**
 * @author Cfeng
 * Programmer也是一种职员,就是对普通职员的扩展,所以继承Employee
 */

import pers.Cfeng.groupsheduing.service.Status;

public class Programmer extends Employee {
     
	//增加的属性有状态,成员ID,领用设备
	private int memberId;//这里还没有设置,要选择的时候才会设置
	private Status statu = Status.FREE;
	private Equipment ept;
	public Programmer(int id, String name, int age, double salary, Equipment ept) {
     
		super(id, name, age, salary);
		this.ept = ept;
	}
	
	public int getMemberId() {
     
		return memberId;
	}
	public void setMemberId(int newId) {
     
		this.memberId = newId;
	}
	
	public Status getStatu() {
     
		return statu;
	}
	public void setStatu(Status newStatu) {
     
		this.statu = newStatu;
	}
	
	public Equipment getEquipment() {
     
		return ept;
	}
	public void setEquipment(Equipment newEpt)
	{
     
		this.ept = newEpt;
	}
	//获得programmer的列表,在原方法的基础上加上职称和设备
	@Override
	public String toString() {
     
		return super.getDetails() + "\t程序员\t" + statu + "\t\t\t" + ept.getInformation();
	}
	
	//获得开发团队的列表,访问权限为protected
	protected String getMemberDetails() {
     
		return memberId +"/" + super.getDetails();
	}
	
	//获得该类成员入选团队的列表
	public String getDetaileForTeam() {
     
		return getMemberDetails() + "\t程序员";
	}
	
}

这个项目很简单,但是适合Java的初学者巩固基础,最开始学习就是要多练习,这里虽然简单,但不影响代码很长,这里就不全部贴出了,需要的我会上传到资源里面,不需要积分~~

你可能感兴趣的:(Java,SE养成,java,mvc,开发语言)