(一)课程设计要求
请根据本学期所学的Java和面向对象的思想实现一个完整的系统。开发环境和工具不限,大作业题目和内容自定,代码总行数不低于800行(含注释)。鼓励围绕这次疫情期间产生的学习、生活、工作的需求来开发相应程序。
具体要求如下:
(二)心理健康测评系统设计
目录
一、需求分析
1.1、开发环境
1.2、功能需求
二、系统分析与设计
2.1、本程序需解决的关键技术问题
2.2、总体功能图
2.3、类图
2.4、程序流程图(功能函数)
三、程序设计与实现
3.1、项目文件组织结构
3.2、程序设计
3.3、程序实现
四、系统测试
4.1测试目的
4.2 测试范围
4.3测试情况
4.4测试时的发现
五、本程序高内聚低耦合的特点,易扩展、易维护
1.高内聚低耦合特点
2.易扩展性、易维护性的特点
六、总结与体会
6.1开发过程中遇到的困难及如何克服困难
6.2个人收获、得到的启示或教训
6.3大作业创意点
6.5通过大作业的完成深入理解的知识点及得到了哪些方面的锻炼
6.6高效学习Java语言与实践技能的建设性意见和建议
七、自评
7.1 自评分
7.2 自评语
操作系统及版本:macOS 12.2.1
开发工具及版本:JDK版本:17.0.2 IDEA版本:2021.3.2
近两个月来,我市疫情多次反复,导致我校不得不长期采取封校措施确保学生的安全。这也使同学们数十天无法外出、节假日无法回家、网购不通,学生抵触心理渐重。况且,大学生作为一个特殊的社会群体,他们还有许多自己特殊的问题 如对新的学习环境和任务的适应问题;对专业的选择与学习的适应问题;理想与现实的冲突问题;人际关系的处理与学习、恋爱中的矛盾问题以及对未来职业的选择问题等等。因此,进行及时的心理健康测评十分必要。此心理健康测评系统可以实现对学生的疫情相关心理测评、压力应对心理测评,在此项目中,我们进一步扩大测评范围,对数月居家线上教学的老师们也纳入测评对象,了解老师们的心理状况。这也使各大高校对心理健康测评系统的需求大大增加。
2.1.1.如何从现实生活中提取对象:从日常生活中的心理健康测评系统出发,测评的对象有每位学生、每位老师,操作此系统的为某管理员,此三种对象分别属于学生类,老师类,管理员类,这三个类都有一些共同的属性,将其提取出来作为普通人类的属性,并作为父类,由学生类、老师类,管理员类继承。
2.1.2.如何运用多态、运用哪种类型的多态
(1)继承产生的多态:首先将普通人类定义为抽象类,内部定义登录,注册的抽象方法,学生类,老师类继承普通人类并重写以上方法。在心理健康测评测试类中使用向上转型实现多态。
(2)接口产生的多态:考虑的用户需求,学生类和老师类均实现疫情相关心理健康测评接口,在心理健康测评测试类中运用向上转型分别使此测评接口引用指向学生类和教师类对象,由此实现多态。
2.1.3如何合理的设计并运用接口提高代码的可扩展性:
将每个测评类型如压力应对心理测评设计为一个接口 ,每个接口中有开始测评和测评结果分析两个抽象方法。可扩展性的体现:后续对其他类型的需求增加,只需设计出对应的接口,内部有测评和测评结果分析的抽象方法。然后让相关类实现此接口即可,对整体的代码并不需要做较大改动。
2.1.4 用户注册功能中如何获取验证码设置密码,验证码多次输入错误如何处理:
通过使用Random类获取(验证码位数可调)随机数;将获取验证码的相关代码封装为getCode()方法,采用递归处理验证码多次输入错误的情况。
2.1.5如何实现文件读写并进行异常处理:
IO字符输入输出流,使用try catch语句进行异常处理。
3.1.1项目文件组成
3.1.2关系:所有类及接口位于com.zzh包下,软件包com.zzh 处于模块lab7 内,而整个模块为项目HelloJava的内容之一。
3.2.1、普通人类
3.2.2、学生类
<1>epidemicTest():用户可选择此功能进行疫情相关心理健康测评;系统会根据用户每道题与最佳答案是否一致判断每道题的正误,返回正确的题目数。在测评结束后,用户可根据需求查看,每道题的结果及正确答案。
<2>epidemicTestAnalyse():将参数设计为int类型的count变量,系统可根据传入的数进行分析,不同大小等级的数可得到不同的测评分析。用户可选择此功能查看疫情相关心理健康测评结果;将返回值设计为String类型,便于将测评结果导入集合中的目标对象,实现用户信息同步(测评结果是学生类的成员属性之一)。
<3>register():为了后面在测试类,系统能够找到目标对象将测评结果导入集合,便将返回值设置为String类型,返回用户密码,将其作为集合元素遍历时寻找目标对象的关键信息,找到目标对象后,调用目标对象.set方法即可。注册首先需要用户输入基本信息进行绑定,在排除用户名重复后,设置密码并确认密码即可。
<4>getCode():此方法的设计,主要是为了解决验证码多次输入错误需重新输入的问题,同时将获取验证码并设置密码的功能封装为一个独立的方法具有一定的合理性。本方法通过方法的重复调用(类似于递归),在验证码输入错误时能够重新运行此方法;获取验证码主要通过Random类的nextInt()进行操作,此处还可以对验证码位数进行设置。
<5>login():用户可通过输入学号和密码进行登陆,将返回值设计为boolean类型可便于在测试类中使用if语句对多种情况如密码错误、用户名不存在等进行提示。
3.2.3老师类
3.2.4管理员类
<1>search():设计此方法可以实现对目标用户信息及测评结果的查看,为了提高用户的可操作性,提供按姓名查询、按学号/工号查询两种方式,主要通过switch语句和对集合元素遍历实现。
<2>showOneStu()、showOneTea():设计此类型的方法,主要是因为在显示、查看用户信息时需要对此类型代码进行重复编写,将其封装成一个方法可以很好的提高代码的复用性。此外将其参数分别设计为学生类和老师类的对象,就可以很好的解决用户属性的获取问题。
<3>showStudent()、showTeacher():设计此类型方法,可以使用户在管理员端根据需求决定是否仅显示学生用户信息、仅显示教师用户信息或全部显示。方法主要通过遍历学生类、老师类集合,分别调用showOneStu()、showOneTea()实现。
<4>printFile():此方法的设计主要是为了在管理员端实现在文件层次对信息的储存。此功能仅对管理员开放权限。方法的实现具体通过调用BufferedWriter的相关方法实现,同时利用try catch进行异常处理。
<5>readTxtFile():此方法的设计主要是为了使管理员能够读取已存入文件的用户信息。此功能仅对管理员开发权限。方法的具体实现通过调用BufferedReader包装类中的相关方法循环读取文件中的数据,同时利用try catch进行异常处理。
3.3.5心理健康测评测试类
<1>menu():设计此方法用于显示主界面,并为用户提供功能选择-进入管理员端、学生端或教师端、退出系统、查看关于系统。
<2>about():设计此方法用来显示本作业的基本信息,包括程序名称、版本、完成时间,姓名、学号、班级等信息。可使用户进一步理解系统相关信息。
<3>manager():设计此方法可实现管理员端的功能正常运行。用户在注册登陆成功后可使用相应功能,包括查看、显示、储存和读取文件信息等功能。具体通过定义的管理员类的上转型对象调用管理员类内重写的登陆、注册方法;然后进行向下转型,得到管理员类对象,继续调用管理员类内的特有方法实现查看、显示、储存、读取功能。
<4>studentManager():设计此方法可实现学生端的功能正常运行。用户在注册登陆成功后可使用相应功能,包括进入疫情相关心理健康测评、压力应对心理健康测评、查看对应测评结果及退出登陆等功能。具体通过定义的学生类上转型对象调用学生类中重写的相关方法来实现。
<5>teacherManager():设计此方法可实现教师的功能正常运行。用户在注册登陆成功后可使用相应功能,包括进入疫情相关心理健康测评、查看对应测评结果及退出登陆等功能。具体通过定义的教师类上转型对象调用教师类中重写的相关方法来实现。
3.3.6疫情相关心理健康测评接口
(注:压力应对心理健康测评接口与之类似,在此不做详细介绍)
<1>epidemicTest():实现类重写该方法后,可设计具体的测评方法。
<2>epidemicTestAnalyse(int count):与测评方法配套,将测评方法的返回值作为参数,由实现类重写,根据传入的参数值设计对应的具体测评分析。
3.3.1在学生类/教师类的epidemicTest()方法的设计中,考虑到用户实际的需求,往往需要储存用户每一道题的答题结果及正确答案,使用户在测评结束后可根据需求选择是否查看每道题的答题情况。此处我定义了两个数组:boolean类型的answer数组、String类型的correct数组,分别储存答题正误情况及正确答案。在用户输入每道题答案后对数组元素分别进行赋值。在最后利用for循环对每道题的答题情况进行显示。如下:
for(int i=0;i<10;i++){
System.out.println("第"+(i+1)+"题:"+answer[i]+" 正确答案:"+correct[i]);
}
3.3.2 为了贴近现实情况,选择了通过获取验证码设置密码,完成新用户注册的流程。验证码类似于随机数,程序采用了Random类的nextInt()方法获取随机数,验证码的具体位数可通过如下代码调节(ss.nextInt(10000) + 1000),默认为四位数。为了提高程序健壮性,需考虑到边缘情况,如密码两次输入不一致,此情况直接提示错误即可,返回“null”,在注册方法中提示重新注册;对于验证码输入错误,程序除了进行错误提示,还采用了类似于递归的方法进行处理,保证用户可以持续获取验证码直到输入正确。核心代码如下:
public static String getCode(){
……
else {
System.out.println("验证码错误!请点击重新获取");
new Scanner(System.in).nextLine();
//采用递归,处理验证码输入错误的情况
return getCode();
}
3.3.3 为了使管理员能够在管理员端查看用户的测评结果,将测评结果设计为
了普通人类、学生类(特有的压力应对测评结果)中的一个成员属性。此时学生、教师大部分信息都是在注册时被添加进对应的集合,而测评结果则是在测试类进行了测评后得到。此处为了将测评结果导入目标对象所在的对应集合,实现信息同步,我将注册方法的返回值设计为String,利用注册方法返回的用户的密码,然后将密码作为关键信息通过集合遍历找到目标对象,在将测评结果导入学生类/老师类集合中。具体代码如下:passwords=teacher.register();
…………
String analysis=teacher2.epidemicTestAnalyse(counter) ;
System.out.println(analysis);
for (int i=0;i
Teacher ss=Teacher.array2.get(i);
//利用注册方法返回注册用户的密码,根据密码搜寻到目标对象,再将测评分析导入学生类集合中
if(ss.getPassword().equals(passwords)){
ss.setAnalysis(analysis);
}
}
3.3.4 程序在每一层功能菜单中都提供了退出功能,包括退出系统、退出学生端/老师端/管理员端、退出登陆。每一层功能选择都通过switch语句控制。在测试类中,在学生端的功能选择的循环内部,登陆功能的分支内使用了一个while循环使用户可实现多次功能选择,但此时一个break语句,仅能够跳出内部的switch语句,却无法跳出while循环。此处我采用了break语句的标记法,将标记放在学生端switch语句外部,即可实现跳转到目标位置。如下:(注:此处出现了四重循环)
System.out.println("\t\t 欢迎进入心理健康测评教师端 \t\t");
while (true) {
……
System.out.print("\t 请输入您的功能选择:");
String choice = sc.next();
//采用标记,使break退出多重循环,达到指定位置,此处跳出外部switch循环,达到退出登陆的目的
ok:
switch (choice) {
case "1":
passwords=teacher.register();
break;
case "2":
if (teacher.login()) {
System.out.println("登陆成功!");
while (true) {
String option = sc.next();
switch (option) {
……
case "3":break ok;
}……}……}
}
发现程序可能出现的问题、潜在的bug;为开发过程提供信息,判断程序是否满足实际的质量要求;对程序各方面功能进行评估,测试执行进度是否在预想内;预防缺陷,提高程序、产品质量;增加开发者信心
4.2.1功能测试:数据输入是否异常、注册、登陆、进行测评及查看测评结果功能、退出功能、管理员端查看、显示功能、是否具有文件读写功能
4.2.2性能测试:CPU、测试环境与生产环境配置、内存、网络、启动时长
4.3.1测试用例覆盖情况:
4.3.2测试所花费时间:七分钟
4.3.3测试工具使用情况:使用了postman进行了接口的测试、使用了Coverity进行了代码扫描
4.4.1测试中遇到的典型错误的表现形式:
4.4.2定位错误点的判断方法、测试手段:IDEA出现报错并自动定位错误点;使用debug进行测试
4.4.3从健壮性出发实施的测试:
本程序在lab7模块下完成,主要从类、接口的层次上分析内聚和耦合性。程序由普通人类、学生类、教师类、测试类、疫情相关心理健康测评接口、压力应对心理健康测评接口构成。每个类的独立性较高。每个类的成员方法只完成一件事。如老师类、学生类、管理员类中都具有注册、登录的成员方法,并且只负责注册和登录。类与类之间、成员方法之间的交互复杂度较低;另外由于本程序采用了类的继承,因此必然存在耦合关系。此外,在管理类、老师类都调用了学生类定义的getCode方法,出现了一定的耦合。除此之外,每个类及成员方法都独立地完成某个特定的子功能。
本程序将心理测评的功能设计为了对应的接口,同时将普通人类设计为了抽象类。当用户的需求出现改变时,如需要增加其他的测评类型。此时我们只需要另外设计出对应的测评功能接口,让需要进行该测评的类实现该接口即可。又如测评系统有了新的测评对象,以工作人员为例。此时,我们也只需要设计出工作人员类,使其继承普通人类,同时实现需要测评的对应接口,程序的其他代码并不需要做出过多的改动。此处对扩展(测评类型、测评对象)开放,对修改关闭(测评接口、普通人类内容不变),这也是开闭原则的很好体现。总之以上几点很好的体现了程序的可扩展性、可维护性。
6.1.1
6.1.2
6.1.3
6.1.4
解决:采用了JAVA IO流的BufferedWriter和BufferedReader包装类,创建对象后调用writer方法即可读入。结合程序特点,使用for循环进行多次读取数据就可以将已存在的信息全部读入即可;
同时对原有的文件名/文件路径进行修改,查阅资料后发现Window系统的文件名与Mac系统有所不同,学习了一些Mac电脑终端命令后,得到了正确的文件名/路径:/Users/peach/Desktop/stu.txt目标文件也按照指令读入了相关用户信息。
6.1.5
解决:学习Java IO流相关知识后发现信息的储存时调用的writer方法为按字符读入,不自动换行。只需在每行信息读入后加一个newLine()方法可以使信息按行读入文件。
6.1.6
6.2.1收获与启示
6.2.2开发过程中得到的教训:刚开始学习多态时,总是为了使用多态而去使用多态,想很多办法去体现多态。忽略了重要的一点:为什么要去使用多态?思考后,我认为使用多态不是为了单纯的体现多态,而是要利用其在程序设计方面具有的优点优化程序。如可以提高代码的复用性、提高程序的可扩展性及可维护性。
6.3.1程序的功能功能较多、较为齐全,能够很好的满足用户的需求
6.3.2程序的功能设计很多方面都贴近实际,如注册时需输入电话号码获取验证码,验证码输入错误也可以重新获取;除此之外,功能也按照现实需求设计,如只对学生开发压力应对心理健康测评,只对管理员开发保存信息至文件、读取文件信息的功能。
6.3.3程序面向了学生、教师、管理员三种对象设计了学生端、教师端、管理员端三个操作平台。针对不同的操作平台,设计了不同的功能体系。
6.4实际想法与最初想法的差异与不足:
最初我想设计一个类似于心理健康测评小程序的系统。它可以实现用户信息的实时储存,即使此次退出了系统,下次登录后,输入设置好的密码依旧能够重新登录,并可以查看之前的测评记录也可以重新进行测评。但实际设计时,发现很难利用所学知识解决这个问题,因为程序运行时,信息储存在ArrayList集合中,程序终止运行后,里面的信息全部就会被清空。于是将大部分精力花在了扩展现有程序的功能上。现有程序只能在管理员端实现简单的文件读写功能。
6.5.1深入理解的知识点:多态、接口、抽象类、类与类之间的继承关系
6.5.2获得到的锻炼:能够根据现实情况及需求清晰的构建出一个系统的大体功能框架,并对其进行概要设计和详细设计。如在设计心理健康测评系统时,根据使用对象:学生、教师,操作对象:管理员,提取共同属性确定继承关系。然后设计主菜单,主菜单可选择进入学生端、教师端或管理员端。每个操作端都应该具有注册和登录功能。登录成功后,又应该要有一层功能选择体系,每一层功能选择都应该包含退出功能的选项。在设计好具体的框架后就对每个部分进行详细设计。
首先要找到优秀可靠的学习资源并深入学习,如本学期老师安排的黑马程序员网课。第二是要多实践,即敲代码,当然这是在已经构建出程序的大致框架的前提下进行。先思考后编写代码效率会更高。
最后,学会在有关编程网站多查找各种资料、各种问题的解决办法,经过自己的甄别和自主学习后,形成自己的认识。
98
本系统基于JAVA基础知识实现,同时面向对象进行设计,重点运用了封装、继承和多态的机制。从功能上看,心理健康测评系统具有较为全面的功能,可以满足用户的大多数需求;从程序设计上看,系统实现了文件读写及异常处理的功能 ,且类的设计较为合理;从代码算法上看,创新点不乏,如输入验证码的环节及对应处理、测评方式的设置、题目的设置等。从整体上看,此心理健康测评系统是一个比较完整的系统。但由于所学知识有限,部分功能的设计不是很完美。
**完整代码见
链接:https://pan.baidu.com/s/1n5Q9j9awYOb7QpfS0_UV6g
提取码:6XA8