Java SE项目收尾
Java养成计划
至于为什么要写这个项目,或者说为什么要实现这个项目,是因为之前的socket聊天室项目虽然复杂,但说实话真的不复杂,大部分代码都是在进行界面设计,核心就是TCP/IP通信,再加上线程使用就没有了,简化版就可以看出来,仅仅70行就可以实现核心的文本聊天功能
所以,不管是读者或者是我本身都觉得JAVA SE以这个项目收官不具有代表性,所以接,下来将用时间来实现这个开发团队调度软件,架构使用的MVC设计模式
本项目涉及的知识点: 类的继承性和多态性,对象的值传递、接口,static和final修饰符,特殊类的使用:包装类、抽象类、内部类,异常处理(开发)–不是简单的try-catch,throws
本项目架构主要依据的是MVC设计模式
所谓MVC设计模式就是将项目分层
软件启动时,根据给定数据创建公司部分成员列表
根据菜单提示,基于现有的公司成员,组件一个开发团队
组件过程包括将成员插入到团队当中,或者从团队中删除某位成员,还可以列出团队中现有成员的列表
开发人员包括架构师、设计师和程序员
本项目使用MVC设计模式,将整个项目分为3个包
很显然,这个包的作用就是实现组织调度软件的视图功能,就是向用户显示界面,这里我们为了方便代码的写作速度,就先不引入java web或者界面GUI了,就使用控制台展示
这个包的作用就是提供服务的
这个包是包含软件所操作的对象,这里就是公司的职员
经过Debug发现是在选择设备的方法中将EQUIPMENT写成了EMPLOYEE, 修改后正常
发现是因为设备组和成员组的数量不一致,导致最后一个成员对应的是空内存,加上一个{}解决
成员列表时,没有Programmer列没有对齐,进入类中修改后正常
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();
}
}
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());
}
}
}
*/
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会自动变化
}
}
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", "喷墨"}
};
}
这里解释一下,programmer继承Employee,Designer继承Programmer,Architect继承Designer
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的初学者巩固基础,最开始学习就是要多练习,这里虽然简单,但不影响代码很长,这里就不全部贴出了,需要的我会上传到资源里面,不需要积分~~