结对编程代码互评
结对编程代码互评
本次代码评价基于 lyc 同学的中小学数学卷子自动生成程序(个人项目)进行测试、分析和评价。我和lyc同学一起参加过一些比赛,对彼此的代码风格和处理问题的逻辑都比较熟悉,希望这次能从他的代码中得到新的收获。
代码功能测试
- 基础功能分析测试
按照题目给出的用户和常规操作进行测试。
对应的卷子生成在程序所设置的绝对路径下,命名符合题目要求。
生成试卷进一步增加了难度标题,便于用户分辨,优化了用户体验。生成题目的格式符合规范,各个运算符号添加位置合理,符合题目要求。
- 随机输入测试
这部分测试不按照题目给出的格式进行,而是随机输入不符合要求的字符测试程序。可以看到,程序在遇到无法识别的字符串时会提示输入错误,并自动返回输入字符串前的状态,由此保障了程序的安全性和高可用性。
综上,可以看出 lyc 同学代码实现的功能和效果还是非常好的。
代码分析
这份代码有四个类:
其中Paper和User是实体类,分别定义了试卷和用户的属性和方法,PaperGenerationSystem是试卷产生系统的工具类,Main是程序的入口。
下面具体分析每个类的实现和作用
User
User类有三个属性:分别是类型,用户名和密码
属性名 | 类型 | 含义 |
---|---|---|
type | String | 用户此时的生成试卷的类型 |
username | String | 用户名 |
password | String | 密码 |
构造方法如下
1 | public User(String type, String username, String password) { |
其他方法:
方法名 | 返回值 | 作用 |
---|---|---|
getType | String | 获取用户类型 |
setType | void | 设置用户类型 |
getUsername | String | 获取用户名 |
setUsername | void | 设置用户名 |
getPassword | String | 获取用户密码 |
setPassword | void | 设置用户密码 |
总体来说User类设计逻辑清晰,方法得体。
Paper
Paper类有三个属性:分别是三种难度的运算符号
属性名 | 类型 | 含义 |
---|---|---|
priSign | String[] | 小学试卷操作符号 |
midSign | String[] | 初中试卷操作符号 |
highSign | String[] | 高中试卷操作符号 |
1 | private final String[] priSign = {"+", "-", "*", "/"}; // 小学试卷操作符号 |
Paper类只有一个方法,这也是这份代码做的不太好的地方:一个方法过长,即使注释写的比较清楚,也显得繁杂,可读性较低。
方法名 | 返回值 | 作用 |
---|---|---|
makeQuestion | String | 生成数学题的方法 |
生成算式的逻辑是按照算式元素从左到右的顺序,除了必须的操作数和加减乘除等于符号,根据试卷类型和随机数来决定是否插入每个符号元素。这种方式生成逻辑清晰,便于理解,但是生成过程繁杂,算法性能并不是很好。
PaperGenerationSystem
PaperGenerationSystem类仅有一个属性,是用户信息的存储链表
属性名 | 类型 | 含义 |
---|---|---|
userMessage | List | 存储用户信息的链表 |
PaperGenerationSystem的方法如下:
方法名 | *返回值 | 作用 |
---|---|---|
userInit | void | 初始化用户信息的链表信息 |
generate | void | 程序的主系统 |
PaperGeneration | void | 试卷生成写入函数 |
check | boolean | 查重函数 |
isNumeric | boolean | 判断是否为数字 |
- userInit
使用链表存储小规模的用户信息,避免了数据库的使用,简化了程序。但是在判断登录时,需要遍历链表来比对用户名和密码,效率较低,可以换成hashmap提高查找效率,同时避免用户重复,进而提升程序的工作效率。
1 | public void userInit() { |
- generate
是程序的主系统,实现了 用户交互部分 的功能,由于代码过长,只展示部分代码。这个方法同样有代码过长的问题,可以进一步封装来提高代码的可读性。
-
- 用户登录
1 | System.out.println("-----欢迎来到中小学数学卷子自动生成系统!-----"); |
-
- 难度切换部分
1 | System.out.println( |
-
- 题目生成部分:根据输入是否有数字和数字的范围,来判断是否要生成题目
1 | if (isNumeric(command)) { |
- PaperGeneration
此方法是 试卷生成写入函数,用于
-
- 新建用户对应的文件夹和txt文件
- 将生成的题目经过查重,加序号处理后写入文件
在程序中,文件使用的是绝对路径,因此会在未经过用户同意的情况下,在用户的电脑的对应路径下产生相应的文件夹,可能会造成用户找不到文件的问题,降低用户的使用体验。
由于代码过长,只展示部分代码。这个方法同样有代码过长的问题,可以进一步封装来提高代码的可读性。
-
- 获取系统时间
1 | Date time = new Date(); |
-
- 生成文件,并将查重后的试题写入文件
1 | String dirPath = "D:\\IDEA code\\PaperSystem\\system\\src\\com\\papers\\" + username; |
- check
此方法负责对题目进行查重,主要思路是遍历用户文件夹下的txt文件,逐个对比题目是否重复。这部分有一个小缺陷
1 | // 只有一张卷子不查重 |
我认为在同一张卷子的生成过程中,题目仍需与上面已经生产的题目进行查重处理。
- isNumeric
此方法的作用是判断输入的字符串是否是数字,如果是数字则可能可以进行题目生成处理。
1 | public boolean isNumeric(String str) { |
代码评价
-
优点:
-
- 这份代码的功能实现十分完备,各个判断和边界考虑的清晰周到。
- 类的设计逻辑清晰,易于他人理解。
- 程序的文字提示十分完善,便于用户操作。
- 属性的安全性较好,在适当的地方采用了private和final关键字进行处理。
-
缺点:
-
- 方法的封装不够完善,程序整体的可读性偏差。
- 存储用户信息用的是链表,查找效率较低,可以采用map或者数据库
- 文件生成的路径是绝对路径,单从终端无法得知文件生成在哪里。
- 算法相对较为简单,效率较低,期待可以进行优化。
总体上来说,lyc同学编写的程序还是很值得我去学习的,尤其是在用户体验方面的考虑十分周到,向yc大佬低头!