结对练习,有空就更,没空就不更(已完结)
本人:201521152029 刘子琦
我的小伙伴:201521044150 吴东霖
结对练习
1.大概这也算fork下来了,地址 https://gitee.com/happyfaye/Calculator 。。。(迷)
2.代码审查工具的使用:相较于复制解压还不一定能用,个人推荐在联网情况下。点开eclipse→help→install 新软件(。。。本人eclipse经过汉化,并不知道插件是哪个英文单词,可能是new software吧),在work with一栏中输入网址一路确定下来就可以自动安装了
Findbugs网址:http://findbugs.sourceforge.net/bugDescriptions.html
junit4网址(同理):http://www.junit.org/
egit地址:http://download.eclipse.org/egit/updates
eclemma地址:http://update.eclemma.org/
Findbugs的使用:
对代码Calculator包进行代码审查后发现一个橙黄色潜在警告性BUGS(可修可不修的,划掉),一定要重视起来
经过我本人(有道)的翻译发现 主程序main()里面 成员变量和局部变量重名,易造成优先选择局部变量易导致调用错误。
Junit4的使用:
经过本人对代码的分析,该计算器的核心代码为calculate( )方法,通过对上一个出栈的数据类型判断从而返回一个整数,通过这个整数的值(-1 push()压栈,0 pop()出栈1数字,1出栈2个数字和1个符号)来进行计算。为测试方法能否正确执行设计了4个有效测试用例
从而验证calculate( )方法能够正确从返回数值中确定运算顺序
同时设计三个无效测试用例:输入内容为字符“s” NULL 和“2+3*2” = 1.0 的错误结果
三个无效的测试用例没有通过
eclemme的使用:
将上面的7个例子写在一起并使用eclemme运行得出下图结果,主要能得到这么高覆盖率的结果是一共就写了一个方法。。。。对这一个方法测了无数遍— —。。。
3.阅读Calculator
类,主要实现两个操作数的加减乘除运算,结合CalString
类,扩展Calculator
类实现四则混合运算。
分析:
1.实现输入算数式,并从获得结果
2.实现四则运算的规则并支持括号的使用
3.缺点:没有GUI,不能直观的看到输入和计算过程,需要使用者自己判断输入的正确性(日后有待改进)
实现步骤:
1 .控制台输入有效字符型四则混合算数式formula
2.调用方法isnum( ) 和 issign( )检查formula有效性
3.程序调用内部calculate()方法得到结果
4.将双精度型结果从控制台输出result
核心代码(。。。在老师的帮助下完成):
1 static double calculate(String s) { 2 s += "#"; 3 int i = 0;// 表达式循环条件 4 char c;// 表达式中的一个字符 5 Stack<Double> num = new Stack<Double>();// 操作数栈 6 Stack<Character> op = new Stack<Character>();// 操作符栈 7 op.push('#');// 表达式开始的标志 8 c = s.substring(i, i + 1).charAt(0);// 取出表达式中的一位 9 while (c != '#' || op.peek().toString().charAt(0) != '#')// 没有取到表达式开始或结束的标志'#',就循环计算表达式的值 10 { 11 if (!issign(c)) 12 { 13 int start = i; 14 int end = 0; 15 while (!issign(s.substring(i, i + 1).charAt(0))) 16 17 end = i++; 18 double m = Double.parseDouble(s.substring(start, end + 1)); 19 num.push(m); 20 c = s.substring(i, i + 1).charAt(0); 21 } else 22 { 23 switch (co(op.peek(), c)) 24 { 25 case -1: 26 op.push(c); 27 i++; 28 c = s.substring(i, i + 1).charAt(0); 29 break; 30 case 0: 31 op.pop(); 32 i++; 33 c = s.substring(i, i + 1).charAt(0); 34 break; 35 case 1: 36 37 double a = num.pop(); 38 double b = num.pop(); 39 40 char ss = op.pop(); 41 42 num.push(cal(a, ss, b)); 43 break; 44 } 45 } 46 } 47 return num.peek(); 48 }
通过对字符型输入的符号进行判断从而使用返回值确定计算顺序。
下面为一些运行时截图:
4.附加题:扩展Calculator
类的图形界面,包括“(、)”运算符,实现四则混合运算;
在我们(存疑?)共同的努力下,将Calculator
类的图形化界面代码进行了部分的重构,实现了在图形化界面下的计算器四则混合运算
核心代码:
1 package com.calculator; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 import java.util.Vector; 7 import java.math.BigDecimal; 8 9 public class Calculator { 10 11 // 操作数1,为了程序的安全,初值一定设置,这里我们设置为0。 12 String str1 = ""; 13 14 // 运算结果 15 String result = ""; 16 17 18 19 // store的作用类似于寄存器,用于记录是否连续按下符号键 20 JButton store; 21 22 23 24 // 声明各个UI组件对象并初始化 25 JFrame frame = new JFrame("Calculator"); 26 JTextField result_TextField = new JTextField(result, 20); 27 JButton clear_Button = new JButton("Clear"); 28 JButton button0 = new JButton("0"); 29 JButton button1 = new JButton("1"); 30 JButton button2 = new JButton("2"); 31 JButton button3 = new JButton("3"); 32 JButton button4 = new JButton("4"); 33 JButton button5 = new JButton("5"); 34 JButton button6 = new JButton("6"); 35 JButton button7 = new JButton("7"); 36 JButton button8 = new JButton("8"); 37 JButton button9 = new JButton("9"); 38 JButton button_Dian = new JButton("."); 39 JButton button_jia = new JButton("+"); 40 JButton button_jian = new JButton("-"); 41 JButton button_cheng = new JButton("*"); 42 JButton button_chu = new JButton("/"); 43 JButton button_dy = new JButton("="); 44 JButton button_left = new JButton("("); 45 JButton button_right = new JButton(")"); 46 JButton button_null1 = new JButton(""); 47 JButton button_null2 = new JButton(""); 48 JButton button_null3 = new JButton(""); 49 50 // 计算机类的构造器 51 public Calculator() { 52 53 // 为按钮设置等效键,即可以通过对应的键盘按键来代替点击它 54 button0.setMnemonic(KeyEvent.VK_0); 55 // 其它等效键省略,你可以自行补充完整 56 57 // 设置文本框为右对齐,使输入和结果都靠右显示 58 result_TextField.setHorizontalAlignment(JTextField.RIGHT); 59 60 // 将UI组件添加进容器内 61 JPanel pan = new JPanel(); 62 pan.setLayout(new GridLayout(4, 4, 5, 5)); 63 pan.add(button7); 64 pan.add(button8); 65 pan.add(button9); 66 pan.add(button_chu); 67 pan.add(button_left); 68 pan.add(button4); 69 pan.add(button5); 70 pan.add(button6); 71 pan.add(button_cheng); 72 pan.add(button_right); 73 pan.add(button1); 74 pan.add(button2); 75 pan.add(button3); 76 pan.add(button_jia); 77 pan.add(button_null1); 78 pan.add(button_null2); 79 pan.add(button0); 80 pan.add(button_Dian); 81 pan.add(button_dy); 82 pan.add(button_null3); 83 84 pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 85 86 JPanel pan2 = new JPanel(); 87 pan2.setLayout(new BorderLayout()); 88 pan2.add(result_TextField, BorderLayout.WEST); 89 pan2.add(clear_Button, BorderLayout.EAST); 90 91 // 设置主窗口出现在屏幕上的位置 92 frame.setLocation(300, 200); 93 // 设置窗体不能调大小 94 frame.setResizable(false); 95 frame.getContentPane().setLayout(new BorderLayout()); 96 frame.getContentPane().add(pan2, BorderLayout.NORTH); 97 frame.getContentPane().add(pan, BorderLayout.CENTER); 98 99 frame.pack(); 100 frame.setVisible(true); 101 102 // 事件处理程序 103 104 // 数字键 105 class Listener implements ActionListener { 106 @SuppressWarnings("unchecked") 107 public void actionPerformed(ActionEvent e) { 108 String ss = ((JButton) e.getSource()).getText(); 109 store = (JButton) e.getSource(); 110 str1 = str1 + ss; 111 result_TextField.setText(str1); 112 } 113 } 114 115 // 清除键的逻辑(Clear) 116 class Listener_clear implements ActionListener { 117 @SuppressWarnings("unchecked") 118 public void actionPerformed(ActionEvent e) { 119 store = (JButton) e.getSource(); 120 str1 = "0"; 121 result = ""; 122 result_TextField.setText(result); 123 } 124 } 125 126 // 等于键的逻辑 127 class Listener_dy implements ActionListener { 128 @SuppressWarnings("unchecked") 129 public void actionPerformed(ActionEvent e) { 130 131 store = (JButton) e.getSource(); 132 CalString cal = new CalString(); 133 double res = cal.calculate(str1); 134 result_TextField.setText(str1 + "=" + res); 135 136 } 137 } 138 139 140 141 // 注册各个监听器,即绑定事件响应逻辑到各个UI组件上 142 Listener_dy jt_dy = new Listener_dy(); 143 144 // 监听数字键 145 Listener jt = new Listener(); 146 147 // 监听清除键 148 Listener_clear jt_c = new Listener_clear(); 149 150 151 button7.addActionListener(jt); 152 button8.addActionListener(jt); 153 button9.addActionListener(jt); 154 button_chu.addActionListener(jt); 155 button4.addActionListener(jt); 156 button5.addActionListener(jt); 157 button6.addActionListener(jt); 158 button_cheng.addActionListener(jt); 159 button1.addActionListener(jt); 160 button2.addActionListener(jt); 161 button3.addActionListener(jt); 162 button_jian.addActionListener(jt); 163 button0.addActionListener(jt); 164 button_Dian.addActionListener(jt); 165 button_dy.addActionListener(jt_dy); 166 button_jia.addActionListener(jt); 167 button_left.addActionListener(jt); 168 button_right.addActionListener(jt); 169 clear_Button.addActionListener(jt_c); 170 171 // 窗体关闭事件的响应程序 172 frame.addWindowListener(new WindowAdapter() { 173 public void windowClosing(WindowEvent e) { 174 System.exit(0); 175 } 176 }); 177 178 } 179 180 181 182 @SuppressWarnings("unused") 183 public static void main(String[] args) { 184 // 设置程序显示的界面风格,可以去除 185 try { 186 UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); 187 } catch (Exception e) { 188 e.printStackTrace(); 189 } 190 191 Calculator cal = new Calculator(); 192 } 193 194 }
运行时截图:
小结:
由于个人缺乏更深的代码知识,暂时不能(已经可以)将算数式的输入实现可视化,代码暂时对于我来说有些(并不)复杂,GUI界面编写(并不)存在难度,待我和我的小伙伴商议分工后再确定如何实现在已有的计算器基础上实现四则运算(括号内内容为昨日写完微博后今日对GUI界面改进的意见)。下面PSP图在开发方面+30min 需求分析+2min 懒得修改图片了~
代码测试部分:
a. 需求分析:测试上有哪些详细的需求?
该计算器的核心代码为calculate( )方法,通过对上一个出栈的数据类型判断从而返回一个整数,通过这个整数的值(-1 push()压栈,0 pop()出栈1数字,1出栈2个数字和1个符号)来进行计算。为测试方法能否正确执行设计了相关的有效测试和无效测试案例
b. 设计测试框架, 模拟测试数据:
- (1) 请给出计算模块的测试用例及运行结果
如上图junit4测试使用方法
-
(2) 描述测试过程中遇到的问题以及解决的方案。
。。。。。。主要是eclipse经过汉化对教程中各步骤英文不知道如何翻译造成较大困扰,边查有道词典边进行测试过程消耗很多时间
-
(3) 请展示上面描述的单元测试的每个环节。
=w=如上图,不一一复制
c. 小结与感受:通过测试,是否有效发现了程序计算模块的问题,并给予改进?
成员变量和局部变量重名,易造成优先选择局部变量易导致调用错误。改进方法:换个变量名。。。。。
其他的缺陷。。。暂时没发现
d. 体会代码规范要求(尽量,正在和队友商量代码统一问题)
(1) 良好的设计
(2) 编码规范
(3) 必要的注释