项目要求
用户:小学、初中和高中数学老师
功能:
1. 命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示“当前选择为XX出题”,XX为小学、初中和高中三个选项中的一个。否则提示“请输入正确的用户名、密码”,重新输入用户名、密码;
2. 登录后,系统提示“准备生成XX数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):”,XX为小学、初中和高中三个选项中的一个,用户输入所需出的卷子的题目数量,系统默认将根据账号类型进行出题。每道题目的操作数在1-5个之间,操作数取值范围为1-100;
3. 题目数量的有效输入范围是“10-30”(含10,30,或-1退出登录),程序根据输入的题目数量生成符合小学、初中和高中难度的题目的卷子(具体要求见附表)。同一个老师的卷子中的题目不能与以前的已生成的卷子中的题目重复(以指定文件夹下存在的文件为准,见5);
4. 在登录状态下,如果用户需要切换类型选项,命令行输入“切换为XX”,XX为小学、初中和高中三个选项中的一个,输入项不符合要求时,程序控制台提示“请输入小学、初中和高中三个选项中的一个”;输入正确后,显示“”系统提示“准备生成XX数学题目,请输入生成题目数量”,用户输入所需出的卷子的题目数量,系统新设置的类型进行出题;
5. 生成的题目将以“年-月-日-时-分-秒.txt”的形式保存,每个账号一个文件夹。每道题目有题号,每题之间空一行。
附表-1:账户、密码
账户类型 |
账户 |
密码 |
备注 |
小学 |
张三1 |
123 |
|
张三2 |
123 |
|
|
张三3 |
123 |
|
|
初中 |
李四1 |
123 |
|
李四2 |
123 |
|
|
李四3 |
123 |
|
|
高中 |
王五1 |
123 |
|
王五2 |
123 |
|
|
王五3 |
123 |
|
附表-2:小学、初中、高中题目难度要求
|
小学 |
初中 |
高中 |
|
难度要求 |
+,-,*./ |
平方,开根号 |
sin,cos,tan |
|
备注 |
只能有+,-,*./和() |
题目中至少有一个平方或开根号的运算符 |
题目中至少有一个sin,cos或tan的运算符 |
|
- 一、功能性分析
首先对队友的程序进行功能测试,主要分为以下几个部分:
- 登录验证:登录时有文字提示。当账号或密码输入错误时,无法成功登录程序同时有错误提示;当账号或密码输入未按规定格式以一个空格分隔时,提示格式错误;当输入正确时能够成功登入程序。
2. 出题验证:在输入小于10或大于30的数字时,程序可以进行错误提示;小学初中高中生成的题目均符合要求;登录后可以连续出题;切换类型后也可正常出题;生成的文件命名正确地按照时间命名,题目带有题号,且每题之间空一行。
3. 查重验证:每个账号文件夹下没有重复的题目(包括满足交换律的加法算式和乘法算式)。
4. 切换验证:能够正确切换难度;当出现除小初高选项之外的命令时会提示错误。
5. 保存验证:保存使用的是相对路径,能正确保存文件。
总而言之,经过测试,代码能够按照预期完成全部所需功能,有许多亮点值得借鉴:
- 当账户文件夹不存在时可以自动创建,拓展性高,当新增用户时无需人力添加,这使得代码移植性高,用户无需下载整个程序(带有所有账户的文件夹)。
- 生成题目后,用户可以知道当前账号下题库中所有题目数量,体验感好。
也有一些小细节有待完善:
- 提示语句不够全面,新手用户无法得知所有功能,建议新加“[10,30]:生成题目”
2. 程序运行界面很简洁,不过建议登录界面与程序内部有明显的分隔,用户能更清楚的感受到是否成功登录或成功退出账号,如下图新增分割线(仅示意)。
- 二、代码分析
搭档的工程文件结构如下图所示,结构明确,清晰,通读搭档的代码后颇有收获,下面主要亮出一些搭档在编写代码过程中值得学习的优点以及还需改进的不足之处:
- 优点:
1. 代码规范,命名通俗易懂,代码之间逻辑明确,注释写得十分详细,可读且易读,此处展示“冰山一角”。
2. 熟练使用异常处理,有相应的解决办法,比如解析用户命令输入时,当匹配完常规命令后,检测用户输入是否为数字,如果是数字,就进入生成题目部分,否则提示相应错误,此处运用try catch来捕捉异常十分明智,巧妙地规避了一切异常情况,比如解决了如果检测到是数字,但数字太大无法赋值给int的情况。
3. 熟练使用各种封装函数,能够有效简化代码。如生成文件名时,十分精炼,三行即可实现功能。一些功能函数返回的结果需要供其他方法使用时,直接在传参时调用,一步到位,代码精炼。
4. 程序性能好,没有双重for循环,一重循环得也较少,时间复杂度低。
- 不足:
代码模块设计部分不够合理,导致编写代码时重复率较高。如小学题目生成器、初中生成器、高中生成器的buildExpression方法完全一样,或许比起接口更适合提取为一个抽象类,减少代码重复率。而Teacher类作为一个抽象类,被小学老师、初中老师、高中老师继承,实质上这些类的属性和方法都一模一样,在使用时也是几乎相同的,或许可以直接用一个Teacher类即可 ,以此减少代码重复率。
/** * 老师的抽象类,具有属性:老师类别,账号,密码,出题类型 */ public abstract class Teacher { String type; String ID; String password; String test_mode; /** * 老师类的构造函数,初始化类型,账号和密码 * * @param type 老师的类型:小学,初中,高中 * @param ID 老师的账号 * @param password 老师账号的密码 */ public Teacher(String type, String ID, String password) { this.type = type; this.ID = ID; this.password = password; } } /** * 小学老师类,继承了老师的所有特征 */ class PrimTeacher extends Teacher { /** * 小学老师的构造函数 * * @param type 小学 * @param ID 小学老师的账号 * @param password 小学老师的密码 */ public PrimTeacher(String type, String ID, String password) { super(type, ID, password); } } /** * 初中老师类,继承了老师的所有特征 */ class MidTeacher extends Teacher { /** * 初中老师的构造函数 * * @param type 初中 * @param ID 初中老师的账号 * @param password 初中老师的密码 */ public MidTeacher(String type, String ID, String password) { super(type, ID, password); } } /** * 高中老师类,继承了老师的所有特征 */ class HighTeacher extends Teacher { /** * 高中老师的构造函数 * * @param type 高中 * @param ID 高中老师的账号 * @param password 高中老师的密码 */ public HighTeacher(String type, String ID, String password) { super(type, ID, password); } }
- 三、总结
虽然目标相同,但每个人的实现方法还是千差万别,通过这次互相分析搭档的代码,能够让我们互相了解情况,拓展视野、增长智慧,找到共同进步的道路。比如我学习到了一些未曾了解接触的方法 SimpleDateFormat("yyyy-MM-dd-HH-mm-ss") ,这是一个相互成长的过程。
打破思维的局限,拥抱多元的观点,开阔思维的边界。