四则运算码云地址: https://gitee.com/zyjjj/four_operations
源代码地址: https://coding.net/u/Belong033/p/java-third/git
(由于我的码云出了一些错误,代码上传不了,所以本次就用队友的账号上传)
现有代码功能改进与扩展
-
需求分析:针对现有代码的改进分析,新开发功能的分析。
之前学长学姐们的代码已经可以完成基本的要求了,我们所用的这份代码刚开始只可以实现生成与计算一个运算符的题目,后来添加了括号操作符,也改善了之前代码随机生成代码的情况,现在我们新的代码可以实现随机生成多运算符的题目。类图如下:
-
浏览所有代码考虑代码质量和测试覆盖率
原测试覆盖率
-
好的测试是重构的根本。检查已有代码的测试,看测试用例是否足够覆盖原代码,如果不足,请添加测试用例
原来测试用例不够覆盖原代码,添加的用例分别是第一位为负数的情况、分数和整数进行加减运算的情况,截图如下:
-
修改代码后,检查代码覆盖,看单元测试是否需要修改?测试用例是否需要增加?
-
程序设计:针对新开发功能做设计,建议使用思维导图。
-
代码展示:展示每个功能的核心代码。
\\退出系统
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==b1)
{
j1.dispose();
dl.setVisible(true);
}
//点击“系统”菜单下的“退出”菜单项
if(e.getSource()==b2)
{
System.exit(0);
}
}
\\自动生成题目
public static String createAc(int operator_no) {
// 表达式
String ac = "";
String[] operator=new String[]{"+","-","*","÷"};
Random rand = new Random();
// 括号标记数
int bracket = 0;
// 括号对数
int bracket_no = 0;
for (int i = 1; i <= operator_no + 1; i++) {
// 判断是否存在"(",若存在,判断是否加上")",bracket=0时不加
if (bracket_no != 0 && (bracket = rand.nextInt(3)) != 0
&& ac.charAt(ac.length() - 1) != '(') {
ac = ac + createNum() + ")" + operator[rand.nextInt(4)];
bracket_no--;
}
// 最后生成的数不加括号
else if (i != operator_no + 1) {
// 判断是否生成括号
bracket = rand.nextInt(3);
// backet=0时,不生成括号
if (bracket == 0) {
ac = ac + createNum() + operator[rand.nextInt(4)];
}
// bracket=1时,在表达式前方生成括号,bracket_no+1
else if (bracket == 1) {
ac = "(" + ac + createNum() +operator[rand.nextInt(4)];
bracket_no++;
}
// bracket=2时,在表达式后后方加括号,bracket_no+1
else {
ac = ac + "(" + createNum() + operator[rand.nextInt(4)];
bracket_no++;
}
} else {
ac = ac + createNum() + operator[rand.nextInt(4)];
}
}
// 是否存在未配对的"(",存在就补上
if (bracket_no != 0) {
ac = ac.substring(0, ac.length() - 1);
for (int i = 0; i < bracket_no; bracket_no--) {
ac = ac + ")";
}
}
// 去除多余的运算符
else {
ac = ac.substring(0, ac.length() - 1);
}
return ac;
}
\\计算生成的题目,四个运算符代码太长,取其中之一为例
public void divide(String s)//除法
{
int i=0;
if(s.contains("÷-")) {s=s.replace("÷-", "÷");i=i+1;}
if(s.startsWith("-")) {s=s.substring(1);i=i+1;}
String[] str=s.split("[÷]");
if(str[0].indexOf("/")>-1 || str[1].indexOf("/")>-1)//分数
{
String[] str1=new String[2],str2=new String[2];
if(!str[0].contains("/")) {str1[0]=String.valueOf(Integer.parseInt(str[0])*Integer.parseInt(str[0]));str1[1]=str[0];}
else {str1=str[0].split("[/]");}
if(!str[1].contains("/")) {str2[0]=String.valueOf(Integer.parseInt(str[1])*Integer.parseInt(str[1]));str2[1]=str[1];}
else {str2=str[1].split("[/]");}
if(Integer.parseInt(str1[1]) != 0 && Integer.parseInt(str2[1]) != 0)//分母不为零
{
result =simplefraction(Integer.parseInt(str1[0])*Integer.parseInt(str2[1]),Integer.parseInt(str1[1])*Integer.parseInt(str2[0]));
}else{
if(Integer.parseInt(str1[0])== 0 || Integer.parseInt(str2[0])== 0) result= "0";
throw new IllegalArgumentException("Divisor cannot be zero!");//除数为零时抛出异常
}
}else{
if(Integer.parseInt(str[1]) != 0){//整数
if( Integer.parseInt(str[0])<1000&&Integer.parseInt(str[1])<1000&&Integer.parseInt(str[0])>-1000&&Integer.parseInt(str[1])>-1000)
{
result = Integer.parseInt(str[0])/Integer.parseInt(str[1])+"";
}
else{
throw new IllegalArgumentException("overrun!");}
}else {
throw new IllegalArgumentException("Divisor cannot be zero!"); //除数为零时抛出异常
}
}
if(i%2==1)
result="-"+result;
}
\\文字转换
public void actionPerformed(ActionEvent e)
{
//点击“系统”菜单下的“退出”菜单项
if(e.getSource()==jMenuItem0)
{
System.exit(0);
}
//点击文字转换下的简体中文
if(e.getSource()==jMenuItem1)
{
//创建简体中文的面板对象
MainFrame MF=new MainFrame();
this.remove(this.getRootPane());
this.dispose();
MF.setVisible(true);
}
//点击文字转换下的英文
if(e.getSource()==jMenuItem3)
{
//创建英文的面板对象
MainFrameE MFE=new MainFrameE();
this.remove(this.getRootPane());
this.dispose();
MFE.setVisible(true);
}
//点击开始做题
if(e.getSource()==jButton1)
{
number=jTextField1.getText();
//创建四则运算的面板对象
mainF MF=new mainF();
//移除主框架上原有的内容
this.remove(this.getContentPane());
//加载四则运算面板的对象到主框架
this.dispose();
//令界面可见
MF.setVisible(true);
}
}
-
效能分析
-
程序运行:程序运行及每个功能的使用截图。
首先进入系统
然后输入你想生成题目的数量
最后就可以答题并计时了
参考资料
重构-靠谱程序员的必备技能: https://mp.weixin.qq.com/s/23a8BY_fP168GWLrGLJzrw
JUnit单元测试: http://www.cnblogs.com/happyzm/p/6482886.html
Java覆盖率统计: http://www.cnblogs.com/happyzm/p/6530384.html
效能分析工具: http://www.oschina.net/p/jprofiler
使用方法: http://www.cnblogs.com/bjlhx/p/6668888.html
2.结对编程
-
小结感受:结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。
通过这次编程我觉得有带来1+1>2的效果,因为一个人可能会有拖延症,总是快到deadline才开始做,两个人就会相互督促对方。而且两个人可以讨论,遇到问题可以一起解决,这也比一个人要好得多。由于是结对编程,代码结构以及实现的四则远算系统都是一样的,所以两个人在后期写博客时分工明确也会节省时间,比如一个人画类图,一个人画功能思维导图等等。
现在我要送给队友一个“汉堡包”,先来一片面包,我们已经在同一个宿舍生活了三年,因此彼此都比较熟悉,一些学习方法基本上都是可以互相交流学习的。所以在对于具体的代码编写遇到分歧时,完全可以通过讨论,最后讨论出一种解决方案。而且我的队友比较好相处,在具体的结对工作中相对很轻松。再把肉放上:队友喜欢坚持自己的观点,所以有时候观点不同的话,大部分还是按照队友的想法来,最后再来一片面包:希望队友在以后的学习生活中遇到不同意见时,可以多听听对方的意见,然后可以在专业方向越走越远。
-
描述结对的过程,提供非摆拍的两人在讨论、细化和编程时的结对照片。
-
提供此次结对作业的PSP
PSP2.1 | 个人开发流程 | 预估耗费时间(分钟) | 实际耗费时间(分钟) |
---|---|---|---|
Planning | 计划 | 15 | 10 |
Estimate | 明确需求和其他相关因素,估计每个阶段的时间成本 | 8 | 5 |
Development | 开发 | 150 | 188 |
Analysis | 需求分析 (包括学习新技术) | 6 | 10 |
Design Spec | 生成设计文档 | 0 | 0 |
Design Review | 设计复审 | 8 | 10 |
Coding Standard | 代码规范 | 3 | 3 |
Design | 具体设计 | 10 | 12 |
Coding | 具体编码 | 36 | 21 |
Code Review | 代码复审 | 15 | 11 |
Test | 测试(自我测试,修改代码,提交修改) | 15 | 20 |
Reporting | 报告 | 10 | 8 |
. | 测试报告 | 3 | 2 |
· | 计算工作量 | 10 | 6 |
· | 并提出过程改进计划 | 10 | 15 |