前言:
时隔多日,我们学习完java的面向对象阶段,毕竟需要付诸实践,这个小项目就 作为我们第一个java面向对象解决的项目,接下来就让我们一起进入项目的世界吧
一、项目需求
• 模拟实现一个基于文本界面的 《 项目开发团队分配管理软件 》
• 熟悉 Java 面向对象的高级特性,进一步掌握编程技巧和调试技巧
•主要涉及以下知识点:
Ø 类的继承性和多态性
Ø 对象的值传递、接口
Ø static 和 final 修饰符
Ø 特殊类的使用:包装类、抽象类、内部类
Ø 异常处理
Ø Java 基本语法和流程控制
Ø 数组, ArrayList 集合
二、功能实现
Ø 软件启动时,首先进入登录界面进行注册和登录功能。
Ø 当登陆成功后,进入菜单,首先就可以对开发人员账户和密码进行修改。
Ø 然后可以对开发人员进行增删改操作
Ø 人员添加成功后,根据菜单提示,基于现有的 公司成员 ,组建一个 开发团队 以开发一个新的项目。
Ø 组建过程包括将成员插入到团队中,或从团队中删除某成员,还可以列出团队中现有成员的列表,开发团队成员包括架构师、设计师和程序员。
Ø 团队组建成功,则可以进入项目模块,添加项目,分配开发团队进行开发。
整个项目UML类图。制作不标准,见谅。
系统流程
三、具体模块的实现
1.实现登陆模块。
思路:要实现登陆模块,我们首先应该想到,我们平常登陆账号都是输入账号,密码,匹配你之前注册的账号密码即可登陆成功, 怎么做到我们输入的账号密码和我们提前注册的账号密码匹配呢,这里我们就要想到,我们输入的账号密码都是字符串类型,既然是字符串,我们就可以使用String类的equals方法进行匹配,匹配成功,则登陆成功。
那么,在我们的项目当中,登陆之前我们是肯定要匹配他是否存在于我们的注册账号之中,如果存在,直接登陆, 如果不存在,我们应该让用户先注册,当然,也可以加一个随机数组成的验证码来进一步强化我们的登陆模块。
实例代码
package com.Team.loginAndRegister; /** * @author WangWei * @version 1.0 */ public class LoadingAndRegister { public String user; public String password; public LoadingAndRegister() { } public LoadingAndRegister(String user,String password) { this.user = user; this.password = password; } public void setUser(String user) { this.user = user; } public String getUser() { return user; } public void setPassword(String password) { this.password = password; } public String getPassword() { return password; } } package com.Team.loginAndRegister; import java.util.Scanner; import java.util.ArrayList; /** * @author WangWei * @version 1.0 */ public class LoadingAndRegisterTest { /** * - ArrayList<LoadingAndRegister> a 储存账号密码的集合 * - LoadingAndRegister lr 账号密码类的对象 */ Scanner sc = new Scanner(System.in); private ArrayList<LoadingAndRegister> a = new ArrayList<LoadingAndRegister>(); private LoadingAndRegister lr = new LoadingAndRegister(); /** * 注册方法 * @throws InterruptedException */ public void loginAccount() throws InterruptedException { TSUtility.loadSpecialEffects(); System.out.println("开始注册:"); System.out.println("请输入你的注册账户名称:"); String loginUserName = TSUtility.readKeyBoard(6, false); lr.setUser(loginUserName); System.out.println("请输入你的登陆密码:"); String loginPassword = TSUtility.readKeyBoard(8, false); lr.setPassword(loginPassword); a.add(lr); System.out.println("注册成功,请登陆!"); } /** * 登陆方法 * @throws InterruptedException */ public void loading() throws InterruptedException { Scanner sc = new Scanner(System.in); boolean flag = true; int count = 5; while (flag) { System.out.println("********************"); System.out.println("*** <登录界面> ***"); System.out.println("*** (: ***"); System.out.println("********************"); System.out.println("请输入你的登陆账户名称:"); String userName = sc.next(); System.out.println("请输入你的登陆密码:"); String password = sc.next(); //未注册 if (lr.getUser() == null || lr.getPassword() == null) { System.out.println("未检测到您的账号,请先注册!"); loginAccount(); } else if (userName.equals(lr.getUser()) && password.equals(lr.getPassword())) { System.out.println("登陆成功!欢迎您:" + lr.getUser()); flag = false; } else { if (count == 1) { System.out.println("你的账户已被锁定,已强制退出!"); System.exit(0); } else { count--; System.out.println("登陆失败!用户名或密码不匹配,你还有" + (count) + "次机会! 请重新登陆:"); } } } } /** * 修改用户信息方法 * @throws InterruptedException */ public void updateAccount() throws InterruptedException { boolean flag = true; while (flag) { System.out.println("=====请选择功能====="); System.out.println("1、修改密码"); System.out.println("2、修改用户名"); System.out.println("3、修改用户名和密码"); System.out.println("4、不修改,退出"); System.out.println("==================="); System.out.print("请选择:"); char c = TSUtility.readMenuSelection(); TSUtility.loadSpecialEffects(); switch (c) { case "1": System.out.println("请输入原密码:"); String oldPassword = sc.next(); if (lr.getPassword().equals(oldPassword)) { System.out.println("密码正确,请输入你的新密码:"); String newPassword = sc.next(); lr.setPassword(newPassword); System.out.println("设置成功,请记住新密码!"); break; } else { System.out.println("密码错误,请重新选择!"); } break; case "2": System.out.println("请输入原密码:"); String oldPassword1 = sc.next(); if (lr.getPassword().equals(oldPassword1)) { System.out.println("密码正确,请输入你的新用户名:"); String newUserName = sc.next(); lr.setPassword(newUserName); System.out.println("设置成功!"); } else { System.out.println("密码错误,请重新选择!"); } break; case "3": System.out.println("请输入原密码:"); String oldPassword2 = sc.next(); if (lr.getPassword().equals(oldPassword2)) { System.out.println("密码正确,请输入你的新用户名:"); String newUserName = sc.next(); lr.setPassword(newUserName); System.out.println("请输入你的新密码:"); String newPassword = sc.next(); lr.setPassword(newPassword); System.out.println("设置成功!"); } else { System.out.println("密码错误,请重新选择!"); } break; case "4": System.out.println("退出中"); TSUtility.loadSpecialEffects(); System.out.println("退出成功"); flag = false; break; default: System.out.println("输入错误,请重新输入!"); break; } } } }
当我们注册完毕后,就要进入系统,进行我们的几个操作。
1.完成开发人员的增删改查。
2.完成将开发人员添加到开发团队的操作,删除,修改操作。
3.完成项目模块, 将项目交给开发团队进行开发的操作。以及项目的曾删改查。
那么完成开发人员的增删改查,根据我们的UML类图设计来看,我们至少要完成九个类和一个接口的编写。
通过将employee类,programmer类,designer类,architect类,这四个类是存在继承关系的,目的是为了继承父类的属性。另有三个类,PC,notebook,printer,他们都实现了一个接口,equipment。这几个类完成之后,我们就着手编写NameListService类,这个类的功能主要是完成对我们的开发人员进行增删改查的任务。
NamlistService类里面要注意的问题主要是开发人员的ID问题,要想开发人员的ID随着我们的增加或者删除而增加或者删除,那么我们可以定义一个全局变量,去控制ID的变化。通过增加一个开发人员,我们设置他的ID自增,那么我们删除的时候,从他删除那个位置就开始,因为我们使用的集合来存储开发人员,他的前一个元素被删除之后,那么他的后一个元素就应该到被删除的那个元素的位置,在集合当中的下标就会向前移动。我们要做的就是将该元素的ID相应的减一,那么就会用到循环去找到该下标对应的元素,然后去设置他的ID。示例代码如下
boolean flag = false; for (int i = 0; i < employees.size(); i++) { if (id == employees.get(i).getId()) { System.out.println( "员工:"+ employees.get(i).getName() + "删除成功!"); employees.remove(i); for (i = id; i <= employees.size(); i++) { //这个代码表示,将我们第i个对象从集合中删除之后,我们后一个元素的ID就应该相应的减一。 employees.get(i - 1).setId(employees.get(i - 1).getId() - 1); }
这个就需要结合集合的下标进行理解,大家可以自行画一个图辅助理解。
做完这个我们就需要做开发团队的模块,开发团队模块里面需要注意的就是数据互通的问题。
当我们做到这个部分的时候,进行测试时会发现一个问题,我们无法将我们之前namelist类里面修改过的数据拿过来用,一是因为我们重新创建对象的原因,导致数据发生变化,那么怎么去杜绝此类情况发生呢?有两种解决方案:
一:我们可以把我们需要使用到NameListService类里面的数据的方法的参数改成NameListService类的对象,这样就不会导致我们去创建对象导致数据发生改变。
实例:
public ArrayList<ArrayList<Programmer>> getManyTeam(NameListService nls) throws TeamException {
二:我们可以将NameListService类中的存放开发人员的集合改为静态修饰,那么他的数据就可以共享,当我们这么做了之后,会发现我们测试时他将我们代码块中的内容打印了一遍,又将我们修改好的集合中的内容打印了一遍,这样就不符合我们的要求,这是因为,类加载的时候,会默认打印一遍代码块的内容,那么我们可以对代码块的内容进行一个判断,判断我们存放开发人员的集合是否为空,如果为空,才打印代码块的内容,如果不为空,就打印集合内容。
实例:
{ /* if (employees.isEmpty()) { }*/ 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)); }
项目模块需要注意的就是项目的添加问题,需要去做个判断,不能比如项目中没有团队,而你却添加了。
四、总结
完成这个开发项目,对于新手来说,确实有难度,但是只要去花时间,还是能够完成的。
接下来我分享一下我在这个项目中的所得以及经验。
首先,拿到这个项目之前应该先熟悉流程,理清楚他的逻辑,厘清各个模块之间的关系,再去完成各个模块的内容,因为我们用到的是面向对象的知识,那我们更应该好好地理清各个类之间的关系,继承,实现等等。
完成每一个模块,一定要做好测试,把能找出来的bug尽量找出来,不然等到最后做主控模块来找bug能让你抓狂。
完成这个项目之后,你会对面向对象的知识加一步认知,并且越来越熟悉面向对象的各种特性。以及我们之前学过的各种小知识的查漏补缺。
以上便是我对这个项目的理解。欢迎大家讨论,不足之处,还请见谅,代码如下:
链接:https://pan.baidu.com/s/1SRiTPgvxSC-ytUDfX00k5w
提取码:8bfk
到此这篇关于Java练手小项目实现一个项目管理系统的文章就介绍到这了,更多相关Java 项目管理系统内容请搜索云海天教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持云海天教程!
原文链接:https://blog.csdn.net/ww166955/article/details/120536535