前言
??相信大家在之前的学习当中也有了不少的收获吧,对于自己的能力检验呢,最好的办法就是通过实践啦,那要怎么实践呢,本博主这次主要讲解了这次的实践项目,这次的实践项目是开发团队分配调度的一个软件,那么关于本次项目开发也主要体现了前面JAVA基础知识的相关使用,以及相关知识的熟练度,接下来就和我一起走进本次实践,欢迎大家一起交流学习! |
MVC模式
在这里我们首先介绍一个开发模式:MVC结构 ??MVC 模式(Model–view–controller)是软件工程中的一种软件架构模式,它把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)
??简而言之在本次项目当中的思想在于:把整个项目分成多个部分的耦合; 并且主要分为: ??M 模型块,即抽象父类 ??V 视图块,打印出用户交互信息 ??C 控制块:用于实现对数据的各种操作
实现目标:
1.模拟实现员工基于文本界面的<<项目开发团队分配管理软件>> 2.熟悉Java面对对象的高级特性,进一步掌握编程技巧和调试技巧 3.主要涉及以下知识点: ???? 类的继承和多态性 ???? 对象的值传递、接口 ???? static和final修饰符 ???? 特殊类的使用:包装类、抽象类、内部类 ???? 异常处理 ???? Java基本语法和流程控制 ???? 数组,ArrayList集合
整体结构图:
??首先我们先来看一下关于本次项目的整体一个系统功能的结构图: 它主要是是分为几个重要的板块,关于用户注册登录,开发人员管理,开发团队调度以及开发项目管理. ??了解了系统功能结构,我们接下来再看一下整个项目代码的运行流程,以方便我们进行整体思路的架构还有项目的实现和完成
整体功能实现分析:
??那么从刚才的两张图来说我们可以看出:想要完成整个项目呢,我们总共需要完成四个小模块,而每一个模块都有自己的功能。通过两图可以看出,完成该项目大致的思路都是完成各自模块的增、删、改、查。这几个功能,相信大家都不陌生。难点在于:该项目需要把各个模块相联系起来,虽然第一感觉也不算太难,但真正开始联系的时候可能会出现很多问题,比如博主就遇到了:模块之间的数据衔接有问题: 每次跨模块调用数据时,数据有差异,就很头疼。其实问题在于:每次调用不同类,实例化对象的时候没有注意其内存地址的改变。 ??总之,完成该项目各个模块之间的衔接,一定要注意每个实现功能服务类要返回数据,不然后面调用起来会很麻烦;一定要注意,实例化对象时地址的改变(如果需要多次调用同一个功能类中的数据,尽量只实例化一次,其他的把实例化的对象以参数的形式传递即可)。下面就是博主对该项目的实现思路和理解。
需求分析:
该软件实现以下功能: ???软件启动时,首先进入登录界面进行注册和登录功能。 ???当登陆成功后,进入莱单,首先就可以对开发人员账户和密码进行修改。 ???然后可以对开发人员进行增删改操作 ???人员添加成功后,根据荣单提示,榛于现有的公司成员。组建一个开发团队以开发一个新的项目。 ???组建过程包括将成员插入到团队中,或从团队中删除某成员,还可以列出团队中现有成员的列表,开发团队成员包括架构师、设计师和程序员。 ?? ?团队组建成功,则可以进入项目模块,添加项目,分配开发团队进行开发。
软件设计结构
该软件由以下三个模块组成: ?com.team.view 模块为主控模块,负责对菜单的显示和处理用户操作 ?com.team.service模块为实体对象(Employee及其子类 如程序员等)的管理模块,NanmelistService和TeamService类分别用各自的数组来管理公司员工和开发团队成员对象 ?ProjectService 是对项目的操作对象类 ?domaln模块 为Employee及其子类等JavaBean类所在的包 ??当然啦,这里也可以采用MVC模式,道理是一样的
具体实现
用户注册登录模块:
????????定义一个LoginView类
???实现注册方法 ????▼如果没有账户则需要注册 ????▼如果有账号则直接进行登录
???实现登录功能 ????▼判断用户输入的值是否正确 ????▼如果正确则进入软件菜单 ????▼如果错误则重新输入,限制次数只有5次,超过次数则程序停止,重新启动
???修改用户密码功能 ????▼可以实现对用户名,密码,或者两者都可以进行修改即可。
开发人员管理模块:
??该模块主要的难点在于:我们需要先存储不同员工的数据,每个类型的员工我们需要建立相应的类,然后通过继承来将几个类之间联系起来。建立每个类时,我们需要想清楚该类有哪些属性,哪个属性是可以继承的,哪个属性是自己独有的。博主这里是通过集合来存储的数据。 首先 ????????在NameListService类中完成功能操作 ??●实现员工的添加(根据职业添加(无, 程序员,设计师,架构师) ) ??●实现员工的修改(至少修改员工的姓名,年龄,工资) ??●实现员工的删除(注意员工id需要动态显示,也就是删除后,员工id需要更新)实现员工的查看(显示所有数据)
?? 说明 ???getAllEmployees()方法:获取当前所有员工。 ??????返回:包含所行员工集合 ?? ?getEmployee(id:int)方法:获取指定ID的员工对象。 ??????参数:指定员工的ID ??????返回:指定员工对象口 ??????异常:找不到指定的员工 ?? 在service子包下提供自定义异常类:TeamException ?? 另外可根据需要自行添加其他方法或重载构造器
数据的添加:
employees.add(new Employee(count, "马云 ", 22, 3000));
employees.add(new Architect(++count, "马化腾", 32, 18000, new NoteBook("联想T4", 6000), 60000, 5000));
employees.add(new Programmer(++count, "李彦宏", 23, 7000, new PC("戴尔", "NEC 17寸")));
employees.add(new Programmer(++count, "刘强东", 24, 7300, new PC("戴尔", "三星 17寸")));
employees.add(new Designer(++count, "雷军 ", 50, 10000, new Printer("激光", "佳能2900"), 5000));
employees.add(new Programmer(++count, "任志强", 30, 16800, new PC("华硕", "三星 17寸")));
employees.add(new Designer(++count, "柳传志", 45, 35500, new PC("华硕", "三星 17寸"), 8000));
employees.add(new Architect(++count, "杨元庆", 35, 6500, new Printer("针式", "爱普生20k"), 15500, 1200));
employees.add(new Designer(++count, "史玉柱", 27, 7800, new NoteBook("惠普m6", 5800), 1500));
employees.add(new Programmer(++count, "丁磊 ", 26, 6600, new PC("戴尔", "NEC17寸")));
employees.add(new Programmer(++count, "张朝阳 ", 35, 7100, new PC("华硕", "三星 17寸")));
employees.add(new Designer(++count, "杨致远", 38, 9600, new NoteBook("惠普m6", 5800), 3000));
??值得注意的是,这里存储时,是通过new 对象,将数据以对象的带参构造器传入的数据。用该方法传递数据,需要在该类里重写toString方法,不然的话,得到的只是该对象的地址,数据并没有成功地传入。
??数据的删除: 我们在删除数据时,需要将员工的号码也前移一位,这样得到的数据看着才更顺畅。我们可以通过循环遍历删除过后的数据,使得他们的号码依次减一:
数据的返回:
public ArrayList<Employee> getAllEmployees() {
return employees;
}
public Employee getEmployee(int id) throws TeamException {
for (int i = 0; i < employees.size(); i++) {
if (employees.get(i).getId() == id) {
return employees.get(i);
}
}
throw new TeamException("该员工不存在");
}
??完成基本的功能之后,最重要的是我们需要将的到的数据作为返回值返回,以便于下一个模块对其的调用。这里博主写了 开发人员数据的返回,以及得到某一个员工数据的返回。 ??这两个返回方法,在添加团队成员时,可以用到。
开发团队调度模块:
??该模块的主要难点在于:把最后的主界面和开发人员管理模块相联系起来,这就要注意参数的传递要准确。 就比如,博主在添加团队成员,调用开发人员的模块时发现,在主界面对开发人员实现的增删改查后的数据,在团队模块里找不到了!得到的只是开发人员模块里初始化的数据。这个问题,博主改了好久,想起都头疼!问题在于:在团队模块调用数据时,new了新对象,在主界面也new 了新对象,也就是说:主界面进行的增删改查后的数据,只保存到了主界面,而团队模块只是重新调用了开发团队的数据! 最后,博主才把主界面的对象做为参数传到了团队模块,才完善了该功能。
需求说明
----------------------・ ゚*。・゚??。需求说明。??・ ゚*。・゚----------------------
如果添加操作因某种原因失败,将显示类似以下信息(失败原因视具体原因而不同): 1-团队列表 2-添加团队成员 3-删除团队成员 4-退出请选择(1-4): 2 ------------------------------------------添加成员--------------------------------- 请输入要添加的员工ID: 2 添加失败,原因:该员工已是某团队成员 按回车键继续…
失败信息包含以下几种: (需要抛出自定义异常) ??成员己满,无法添加 ??该成员不是开发人员,无法添加 ??该员工已在木开发团队中 ??该员工已是某团队成员 ??团队中至多只能有一名架构师(以下判断可借用instanceof进行判断) ??团队中至多只能有两名设计师 ??团队中至多只能有三名程序员
团队的创建:
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(("BUSY".equalsIgnoreCase(p.getStatus().getNAME()))) {
throw new TeamException("该员工已是某团队成员");
}else if ("VOCATION".equalsIgnoreCase(p.getStatus().getNAME())){
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 if (team[i] instanceof Programmer){ numOfPrg++;}
}
if (p instanceof Architect) {
if (numOfArch >= 1)
{throw new TeamException("团队中至多只能有一名架构师");}
} else if (p instanceof Designer) {
if (numOfDsgn >= 2)
{throw new TeamException("团队中至多只能有两名设计师");}
} else if (p instanceof Programmer) {
if (numOfPrg >= 3)
{throw new TeamException("团队中至多只能有三名程序员");}
}
team[total++] = p;
p.setStatus(Status.BUSY);
p.setMemberId(counter++);
}
??我们可以先调用增删改查后,开发人员的数据,得到想要存到团队里的员工ID,添加到创建的数组中。在添加团队成员时,按照添加团队成员的要求,设置判断语句限制添加成员的类别和数量。 ??在创建团队时,我们可以在第一个团队创建后,在退出这里,把团队的数据保存到一个新建的集合里,然后初始化团队的数据,以便于下一个团队可以像第一个团队那样重新添加团队成员
开发团队调度管理模块
参考实现: TeamService类的设计:
功能:关于开发团队成员的管理:添加、删除等(还需要自行实现)。 说明: ???counter为静态变量,用来为开发团队新增成员自动生成团队中的唯一ID, 即memberld (提示:应使用增1的方式) ???MAX_ MEMBER:表示开发团队最大成员数 ???team数组:用来保存当前团队中的各成员对象(也可以用一个新的集合) ???total:记录团队成员的实际人数 说明: ???listSvc 和teamSvc属性:供类中的方法使用 ???enterMainMenu ()方法:主界面显示及控制方法。 ???以下方法仅供enterMainMenu()方法调用: ?????listAllEmplovees ()方法:以表格形式列出公司所有成员 ?????getTeam()方法:显示团队成员列表操作 ?????addMember ()方法:实现添加成员操作 ?????deleteMember ()方法:实现删除成员操作
开发项目管理模块:
该模块需要实现的功能主要就是把添加进来的项目,随机分配给团队。 ??实现项目的添加 (添加参考的项目) ??实现项目的分配 (团队随机分配一个项目进行开发) ??实现项目的查看 (显示所有项目及是否被开发) ??实现项目的删除 (被开发中的项目不能被删除) ??不过我们需要注意的是,在分配时,我们要根据项目的状态这个属性来判断该项目是否被开发,以便于后面执行分配时,避免重复分配,以及项目没有确保分配到团队中。在这里,我们采用了一个while循环判断:
Random ra = new Random();
int ranNum = ra.nextInt(pro.size());
Project project = this.pro.get(ranNum);
while (project.getStatus())
{
ranNum= ra.nextInt(pro.size());
project=this.pro.get(ranNum);
}
project.setTeamName(teamName);
project.setTeam(team);
project.setStatus(true);
pro.set(ranNum, project);
在处理异常时,我们可以重写异常输出的信息,以便于代码更好的可读性。
try {
throw new TeamException("该项目不存在");
} catch (TeamException e) {
e.printStackTrace();
}
在domain包中完成项目实体类Project的创建 在service包中完成项目操作类ProjectService的创建 ??其他还需要的方法属性可自行添加
主界面的实现
IndexView类的设计 ??最后在view包中编写项目程序运行主界面类IndexView ??将前面4个模块的内容装在一起,并运行软件,操作基本功能,调试bug,项目开发完成。
总结
??本项目的实现还是具有一定的难度,该项目主要的难点在于:让每个模块相互衔接,以及各个模块之间数据的参数传递要准确,还有就是在创建集合或者数组保存数据时,注意集合或者数组的初始化,保下一次数据的存储不会受到影响。该项目是博主写的第一个较大的项目,写了好久,中间遇到了很多的问题,也修改了很久。有时候遇到的问题也相当头疼,幸好在老师的帮助下,把问题解决掉以后,瞬间豁然开朗的那种感觉,还是挺不错的。在遇到难以解决的问题,或者自己已经花了很多时间都没有解决掉问题时,别头铁(一股脑地自己改,可能会越改越麻烦!),多和同学、老师交流请教,
??最后附上本次项目的代码文件,欢迎下载。
链接:https://pan.baidu.com/s/1HAMHxc4gOKGSlqzJ-pGA_g 提取码:sy52 代码源文件
|