作业基本信息
这个作业属于哪个课程 | <福州大学计算机学院软件工程> |
---|---|
作业要求 | 软件工程实践第一次作业 |
作业目标 | 实现简单的可视化计算器 |
其他参考文献 |
1. Gitcode项目地址
2.PSP
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
•Planning | •计划 | 30 | 40 |
• Estimate | • 估计这个任务需要多少时间 | 300 | 400 |
Development | 开发 | 70 | 70 |
• Analysis | • 需求分析 (包括学习新技术) | 100 | 200 |
• Design Spec | • 生成设计文档 | 20 | 20 |
• Design Review | • 设计复审 | 10 | 10 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
• Design | • 具体设计 | 20 | 30 |
• Coding | • 具体编码 | 100 | 200 |
• Code Review | • 代码复审 | 10 | 5 |
• Test | • 测试(自我测试,修改代码,提交修改) | 50 | 60 |
Reporting | 报告 | 60 | 60 |
• Test Repor | • 测试报告 | 30 | 20 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 30 |
合计 | 840 | 1165 |
3.GUI及功能展示
4.解题思路
先弄好GUI的样子,之后对各个模块进行实现,每个模块有不同的处理逻辑,最后再把它们串联起来
- 创建一个JFrame作为主窗口,里面包含一个文本框inputField用于显示运算过程和结果。
- 创建数字按钮、运算符按钮、等号按钮、清除按钮等,添加到面板panel中,然后将panel添加到窗口中。
- 为按钮添加ActionListener监听器,在监听器里定义按钮被点击后的处理逻辑。
- 数字按钮点击时,将数字接到输入框文本后面。
- 运算符按钮点击时,记录下当前输入框中的操作数到firstOperand,并记录运算符到operator变量,设置标志位isOperatorClicked。
- 等号按钮点击时,根据记录的运算符operator进行相应的数学运算,计算结果后显示到输入框中。
- 清除按钮点击时,清空所有变量和输入框。
- 对于次方、幂、三角函数等特殊按钮,在其监听器里分别实现相关的数学运算逻辑。
- 在主方法main里创建计算器实例,启动程序。
5.接口设计及实现过程
- 导入需要的Swing和AWT类库
- 定义Calculator类,继承JFrame作为主窗口
- 声明一个文本框inputField用于显示计算内容
- 声明数字按钮数组numberButtons和运算符按钮数组operatorButtons
- 声明等号按钮、清除按钮、两个操作数和一个运算符变量
- 构造函数中设置窗口标题、定义文本框为不可编辑
- 循环创建数字按钮并添加点击监听
- 创建运算符按钮,添加点击监听
- 创建等号按钮、清除按钮,添加点击监听
- 在面板上设置网格布局,添加按钮
- 将面板添加到窗口上
- 数字按钮监听器中处理数字按钮点击逻辑
- 运算符按钮监听器中处理运算符点击逻辑
- 等号按钮监听器中处理计算逻辑
- 清除按钮监听器中处理清空逻辑
- 次方、幂、三角函数按钮的监听器中实现相关运算逻辑
- 设置窗口属性,显示窗口
具体代码实现可以参考开头给出的gitcode项目地址
##关键代码
这个部分是计算逻辑核心,通过用户的点击来作为输入,然后回应
响应数字
public void onNumberButtonClicked(int number) {
if (isOperatorClicked) {
inputField.setText(String.valueOf(number));
} else {
inputField.setText(inputField.getText() + number);
}
isOperatorClicked = false;
}
响应加减乘除
public void onEqualsButtonClicked() {
double secondOperand = Double.parseDouble(inputField.getText());
double result = 0;
switch (operator) {
case "+":
result = firstOperand + secondOperand;
break;
case "-":
result = firstOperand - secondOperand;
break;
case "*":
result = firstOperand * secondOperand;
break;
case "/":
result = firstOperand / secondOperand;
break;
default:
break;
}
inputField.setText(String.valueOf(result));
isOperatorClicked = true;
}
响应三角函数
public void onTrigonometricButtonClicked(String operator) {
double angle = Double.parseDouble(inputField.getText());
double result = 0;
switch (operator) {
case "sin": // 正弦
result = Math.sin(angle);
break;
case "cos": // 余弦
result = Math.cos(angle);
break;
case "tan": // 正切
result = Math.tan(angle);
break;
default:
break;
}
inputField.setText(String.valueOf(result));
isOperatorClicked = true;
}
响应幂函数
public void onOperatorButtonClicked(String operator) {
if (operator.equals("^")) { // 次方操作
double base = Double.parseDouble(inputField.getText());
double exponent = 2; // 默认使用指数为2
double result = Math.pow(base, exponent);
inputField.setText(String.valueOf(result));
} else if (operator.equals("pow")) { // 幂操作
double base = Double.parseDouble(inputField.getText());
double exponent = Double.parseDouble(JOptionPane.showInputDialog(this, "Enter the exponent:"));
double result = Math.pow(base, exponent);
inputField.setText(String.valueOf(result));
} else { // 其他操作符
this.operator = operator;
firstOperand = Double.parseDouble(inputField.getText());
isOperatorClicked = true;
}
}
清空计算器
public void onClearButtonClicked() {
inputField.setText("");
firstOperand = 0;
operator = "";
isOperatorClicked = false;
}
6.程序测试
在测试类中添加了setup()方法来初始化计算器实例,并添加了测试正弦、余弦和正切三角函数的方法。
至此,该测试类包含了9个测试方法,覆盖了计算器的所有主要功能,包括加减乘除、次方、清空和三角函数
测试代码
package calculator;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class CalculatorTest {
Calculator calc;
public int pass=0;
@Before
public void setup() {
calc = new Calculator();
}
@Test
public void testAddition() {
calc.onNumberButtonClicked(5);
calc.onOperatorButtonClicked("+");
calc.onNumberButtonClicked(3);
calc.onEqualsButtonClicked();
assertEquals("8.0", calc.inputField.getText());
}
@Test
public void testSubtraction() {
calc.onNumberButtonClicked(5);
calc.onOperatorButtonClicked("-");
calc.onNumberButtonClicked(3);
calc.onEqualsButtonClicked();
assertEquals("2.0", calc.inputField.getText());
}
@Test
public void testMultiplication() {
calc.onNumberButtonClicked(5);
calc.onOperatorButtonClicked("*");
calc.onNumberButtonClicked(3);
calc.onEqualsButtonClicked();
assertEquals("15.0", calc.inputField.getText());
}
@Test
public void testDivision() {
calc.onNumberButtonClicked(6);
calc.onOperatorButtonClicked("/");
calc.onNumberButtonClicked(3);
calc.onEqualsButtonClicked();
assertEquals("2.0", calc.inputField.getText());
}
@Test
public void testPower() {
calc.onNumberButtonClicked(2);
calc.onOperatorButtonClicked("^");
assertEquals("4.0", calc.inputField.getText());
}
@Test
public void testClear() {
calc.onNumberButtonClicked(5);
calc.onClearButtonClicked();
assertEquals("", calc.inputField.getText());
}
@Test
public void testSin() {
calc.onNumberButtonClicked(0);
calc.onTrigonometricButtonClicked("sin");
assertEquals("0.0", calc.inputField.getText());
}
@Test
public void testCos() {
calc.onNumberButtonClicked(0);
calc.onTrigonometricButtonClicked("cos");
assertEquals("1.0", calc.inputField.getText());
}
@Test
public void testTan() {
calc.onNumberButtonClicked(0);
calc.onTrigonometricButtonClicked("tan");
assertEquals("0.0", calc.inputField.getText());
}
}
结果
结果显示所有测试均通过
7.优化改进
-
使用面向对象设计模式:
将数字按钮、运算符按钮抽象成按钮类Button,继承自JButton,扩展对应功能
创建运算类Operator实现各种运算接口
提取界面类、控制类、运算类,降低耦合
代码重复问题: -
按钮创建代码可以提取到工具方法中
各按钮的监听逻辑可提取到公共父类中
运算符的处理逻辑可以用策略模式重构
异常处理: -
加入参数校验,避免数字格式异常
加入异常捕获,防止程序崩溃
界面优化: -
加入科学计算功能,更多运算符
界面布局优化,美化外观
支持键盘输入
新功能扩展: -
支持变量功能
加入图形可视化显示
加入历史记录功能
性能优化: -
用更轻量级的组件替代Swing
运算核心用Native接口优化
8.异常处理
主要需要添加异常处理的地方:
- 数字按钮点击处理逻辑:
try {
inputField.setText(inputField.getText() + number);
} catch (NumberFormatException e) {
// 输入框内容不是数字时,不concat
}
- 运算符按钮点击处理逻辑:
try {
firstOperand = Double.parseDouble(inputField.getText());
} catch (NumberFormatException e) {
// 输入框内容不是数字时,不解析
}
- 等号按钮点击处理逻辑:
try {
secondOperand = Double.parseDouble(inputField.getText());
// 执行运算逻辑
} catch (NumberFormatException e) {
// 输入框内容不是数字时,不解析,不执行运算
}
- 三角函数按钮处理逻辑:
try {
double angle = Double.parseDouble(inputField.getText());
// 执行三角函数运算
} catch (NumberFormatException e) {
// 输入框内容不是数字时,不解析,不执行运算
}
当捕获到异常时,可以给用户提示错误信息,而不是直接崩溃。
9.心得体会
初次做软工作业,有些吃力,不过这次学会了很多,在写计算逻辑部分的时候,感觉用python会好写很多,精度也可能更高,但是估计也更慢了,总的来说收获很多,有了做出一个软件过程中的框架