赞
踩
提前祝大家中秋快乐了呀,时隔多日,我终于开始了 Java 基础 的第三个练手案例。至于为什么这么久才对这个练手案例动刀,说多了都是泪,这段时间新生开学,狗子我还调了宿舍,在搬宿舍的同时,一度被穿着蓝色军训服的大一新生围城 (# ̄~ ̄#)(师兄师姐你们怎么不吃饭)
好了不瞎扯了,后续也要加大力度了,否则被大一的师弟师妹们卷下去就很丢脸。
这次的是基于 Java基础 的第三个练手案例,和前两个一样,依旧是来自于 尚硅谷 的案例,真香 ~ 。在下文中将会对其基于我自己的理解,结合尚硅谷那边的解说逐一介绍案例中的过程和细节,文章可能会有点长部分源码就不放出来了。前两个案例的文章有兴趣的小伙伴可以自行跳转去查看呀!
噢对了,从这边文章开始狗子我的昵称便更改了,并且以后都是这个昵称。至于为什么呢?嗯嗯嗯……毕竟女朋友喜欢这个外号,<( ̄︶ ̄)>。开干!
在开始搞事情之前得先准备好下面这些东西,其中 JDK 和 IDE 不一定需要统一,这只是狗子我使用的版本而已。准备好之后带上我们的脑子就可以开搞啦
在这次案例中和第二次案例一样,同样使用到了 MVC框架 ,将业务层和视图层进行分离,提高了程序的可维护性,降低了耦合性,这一框架模式也是从尚硅谷的教学中学习得来,‘真’ YYDS。在下面中分别对 尚硅谷 和 狗子我个人 的结构图进行展示,我的是基于尚硅谷的进行绘画的,主要是为了更好理解
尚硅谷
狗子本狗
在尚硅谷的文件中提供了已经封装好的 TSUtility 工具类,方便我们实现键盘的访问。由于工具类中涉及到的都已经接触过,因此这个工具类便自己进行了编写,如果是从视频那边过来的话也可以直接跳过工具类的编写,不过还是推荐自己尝试一下。
函数名 | 功能介绍 | 返回类型 |
---|---|---|
readMenuSelection | 用于界面菜单的选择 | int |
readInt | 从键盘中读取一个不超过二位数的整数 | int |
readConfirmSelection | 用于确认选择的输入,读取‘Y’或‘N’ | char |
readKeyBoard | 用于记录用户从键盘中输入的数据 | String |
readReturn | 提示并等待,直到用户按回车键后返回。 | void |
同样在这里附上一小撮截图
这个模块是 MVC设计模式 里面的 M(model), 在这里封装了众多 JavaBean类,如员工职位和设备种类等
Employee类
这是封装了普通员工信息的类,同时也是其余员工的直接或间接父类,其封装内容如下,分别为员工工号、员工姓名、员工年龄以及员工薪资,提供对应的构造器并在本类中重写了 toString()
方法来展示员工信息。
Programmer类
在本类中封装了程序员的信息,这也是加入团队的最低要求。这继承了 Employee 类,同时也是后面 Architect 类和 Designer 类的父类。除了继承了父类的属性之外,还封装了团队编号、状态情况以及设备情况,同时提供对应的构造器并在本类中重写了 toString()
方法来展示员工信息。
Designer类
在本类中封装了设计师的信息,这继承了 Programmer 类,同时也是后面 Architect 类的父类。除了继承了父类的属性之外,还封装了团队编号、状态情况以及设备情况,同时提供对应的构造器并在本类中重写了 toString()
方法来展示员工信息。
Architect类
在本类中封装了架构师的信息,这继承了 Designer 类。除了继承了父类的属性之外,还封装了股票数量属性,同时提供对应的构造器并在本类中重写了 toString()
方法来展示员工信息。
由于在后续的操作中每个成员的设备并不明确,因此在这里定义一个设备接口,后方使用多态性从而减少代码的冗余。在其下面,PC类、NoteBook类 和 Printer类 都分别实现了这一接口并提供了对应的属性和方法(下方放的图是尚硅谷作图的,直接扒过来了)
该模块是 MVC模式 中的 C(control),为实体对象(Employee及其子类如程序员等)的管理模块
这个是采用了尚硅谷的数据类,这里面记录了公司内所有的员工信息
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"}
};
//如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应
//PC :21, model, display
//NoteBook:22, model, price
//Printer :23, name, type
public static final String[][] EQUIPMENTS = {
{},
{"22", "联想T4", "6000"},
{"21", "戴尔", "NEC17寸"},
{"21", "戴尔", "三星 17寸"},
{"23", "佳能 2900", "激光"},
{"21", "华硕", "三星 17寸"},
{"21", "华硕", "三星 17寸"},
{"23", "爱普生20K", "针式"},
{"22", "惠普m6", "5800"},
{"21", "戴尔", "NEC 17寸"},
{"21", "华硕", "三星 17寸"},
{"22", "惠普m6", "5800"}
};
}
这是记录员工状态的类,将构造器私有化,只在类中声明三个对象属性,分别表示成员的空闲、繁忙和休假的状态。
public class Status {
private final String STATUS; //记录用户状态
private Status(String STATUS) {
this.STATUS = STATUS;
}
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 getSTATUS() {
return STATUS;
}
@Override
public String toString() {
return STATUS;
}
}
在本类中自定义了在团队操作过程中的操作异常
public class TeamException extends Exception {
static final long serialVersionUID = -7034897115645766939L;
public TeamException() {
}
public TeamException(String message) {
super(message);
}
}
该类负责将 Data类 中的数据封装到 Employee[] 数组中,同时提供相关操作 Employee[] 的方法。
public NameListService() {
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]); //工资
//特殊工种特定的属性获取
int stock; //声明股票数量
double bonus; //声明奖金
Equipment equipment; //声明设备变量
//通过不同的工种实例化不同的对象
switch(type) {
case EMPLOYEE: {
employees[i] = new Employee(id, name, age, salary);
break;
}
case PROGRAMMER: {
equipment = creatEquipment(i); //programmer 的设备
employees[i] = new Programmer(id, name, age, salary, equipment);
break;
}
case DESIGNER: {
bonus = Double.parseDouble(EMPLOYEES[i][5]); //designer 的奖金
equipment = creatEquipment(i); //designer 的设备
employees[i] = new Designer(id, name, age, salary, equipment, bonus);
break;
}
case ARCHITECT: {
bonus = Double.parseDouble(EMPLOYEES[i][5]); //architect 的奖金
equipment = creatEquipment(i); //architect 的设备
stock = Integer.parseInt(EMPLOYEES[i][6]); //architect 的股票数量
employees[i] = new Architect(id, name, age, salary, equipment, bonus, stock);
break;
}
}
}
}
方法名 | 功能 | 返回值 |
---|---|---|
getAllEmployees() | 获取所有员工信息 | Employee[] |
getEmployee | 通过 id 索引返回员工信息并有可能会抛出异常 | Employee |
creatEquipment | 根据不同的设备号创建不同的设备对象 | Equipment |
在这里封装了关于开发团队成员的管理方法,如添加、删除等,并封装了团队人数、架构师人数、设计师人数、程序员人数、团队最大容纳人数和用于自动生成团队成员编号的静态变量,同时提供了对应的 get() 方法
在这里对本类中的方法进行一个简单的介绍
这个模块是 MVC设计模式 里面的 V(view), 该模块为主控模块,负责菜单的显示和处理用户操作,几乎所有的交互都将在这一模块中完成。在本模块中包含了两个类,分别是 TSUtility 工具类以及 TeamView 类,其中工具类上方已经介绍过了,下面就主要介绍另外一个类。
在本类中通过与用户的交互,逐一实现各个功能。
类内部封装的属性有 listService 和 teamService 变量,都是供类中方法使用的,以及众多方法,通过 enterMainMenu() 方法在显示主菜单界面的同时,通过与用户的交互,从而进行调用其余方法。以下方法仅供 enterMainMenu() 方法调用:
listAllEmployees ()
:以表格形式列出公司所有成员getTeam()
:显示团队成员列表操作addMember ()
:实现添加成员操作deleteMember ()
:实现删除成员操作public void enterMainMenu() {
boolean isLoop = true;
int selection = 0;
// TeamView menu = new TeamView(); //如果写成这样子的话就会出错,公司名单无法更新
while(isLoop) {
if(selection != 1) {
listAllEmployees(); //错误:menu.listAllEmployees();
}
System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):");
selection = TSUtility.readMenuSelection();
switch(selection) {
case 1: {
listTeam(); //团队列表
break;
}
case 2: {
addMember(); //添加成员
break;
}
case 3: {
deleteMember(); //删除成员
break;
}
case 4: {
System.out.print("确认是否退出(Y/N):");
char confirm = TSUtility.readConfirmSelection();
if(confirm == 'Y') {
isLoop = false;
}
break;
}
}
}
}
这里需要注意的是在 enterMainMenu() 方法中注释的地方,狗子我找了半天之后终于找到了这个顽强的 bug((╬━㉨━)凸) ,初步怀疑是因为内存空间分配的原因,但不确定,因此去请教了我的老师。
- 老师给出的答案是在这里如果对该类进行实例化的话(TeamView menu = new TeamView()),就会在内存中生成另外一块空间,那么在调用下方的方法时,就会在这一块堆空间中进行操作,但是团队的对应操作是在本类中的空间进行操作的(因为在主函数中进行了实例化 new TeamView().enterMainMenu()),两块空间由于没有任何联系,因此对团队操作并不会影响到我们申请的 menu 空间,在测试时便会出错,具体 bug 情况可以自己去生产看看效果((ʘ̆㉨ʘ̆))
怎么说呢,这次做的案例收获还是蛮多的,毕竟是结合了前面所学的 Java基础 进行一个整体复习的案例,不像前面两个一样只是部分的。
对于Java基础来说,这个案例是三个案例里面相对全面的,可以较好的梳理和加强对Java三大特性的理解和使用,对之前的那句话 “你不动手,永远停留在想象层面” 感受更深了,毕竟也被一个 bug 折磨了一段时间。
这次的源码已经整理好了,一直决定这里的资源分享好像不太好使,因此抽空去学了一下 gitee码云 的基本用法并整理了这三次的源码放在 gitee 仓库中(别问为什么不放在 github 上,问了就是进入网址得看命)
gitee仓库地址 – > https://gitee.com/Aqting/javacase.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。