结对项目作业GUI
一.Coding.Net项目地址:https://git.coding.net/zhengsh589/CoupleProject.git
二.PSP表格(完成前):
PSP |
任务内容 |
计划共完成需要的时间 |
Planning |
计划 |
一周 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
一周 |
Development |
开发 |
4天 |
Analysis |
需求分析 (包括学习新技术) |
3.5(h) |
Design Spec |
生成设计文档 |
2(h) |
Design Review |
设计复审 (和同事审核设计文档) |
1(h) |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
1(h) |
Design |
具体设计 |
1h |
Coding |
具体编码 |
2天 |
Code Review |
代码复审 |
1(h) |
Test |
测试(自我测试,修改代码,提交修改) |
2(h) |
Reporting |
报告 |
2h |
Test Report |
测试报告 |
1.5h |
Size Measurement |
计算工作量 |
30min |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
30min |
三.结对编程对接口的设计:
在网上查阅了有关于其它资料中关于Information Hiding, Interface Design, Loose Coupling,我了解到以下关于它们的信息:
Information Hiding信息隐藏:信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。
Interface Design接口设计:是传统的后勤保障的一种要素也是一种后勤功能,而面向接口编程是软件工程领域常用的设计手段。
Loose Coupling松耦合:系统通常是基于消息的系统,此时客户端和远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。只要消息符合协商的架构,则客户端或服务的实现就可以根据需要进行更改,而不必担心会破坏对方。
我们的想法和设计:对于模块化设计和界面化设计,我们并不需要知道界面内部如何运行,而我们只利用这些方法对接口设计为只需要调用方法和实现接口就可以,有访问都是通过访问函数实现的。
对于模块化设计,我们在关于界面生成,输入输出,生成题目,计算结果,优先级顺序和互换等方面也都是分开的,互相独立的。
四.模块接口的设计与实现过程:
我们的代码有以下类:Calculate,Command,Create,FileOutPrint,FileRead,MainExp这几个类,Calculate里面包含加减乘除计算结果,Command是控制题目数量还有操作数范围的等等的限制的条件,如按钮和面板控制,等等。Create里面则是生成随机数以及判断算术符优先顺序的方法priority(判断优先级的方法)等,FileOutPrin还有FileRead包括测试的部分,MainExp里面则包含操作符的生成以及算术的范围限制。
以下是我做的一部分代码:
1. 检查用户的答案并计算正确题数:
1 public void checkAnswer() { 2 double result = 0; 3 double userInput = 0; 4 for (int i = 0; i < answer.size(); i++) { 5 if (tfUserAns.get(i).getText().trim().equals("")) { 6 userInput = 1; 7 result = 0; 8 } else { 9 userInput = Double.parseDouble(tfUserAns.get(i).getText().trim()); 10 result = Double.parseDouble(answer.get(i).trim()); 11 } 12 hint.get(i).setVisible(true); 13 // 回答正确的话: 14 if (result - userInput == 0) { 15 hint.get(i).setText("√"); 16 rightNumber++; 17 } else { 18 // 回答错误的话: 19 wrongNumber++; 20 } 21 } 22 }
2. 出题的题条件判断,限制输入的条件:
1 private void addContToMenu(JPanel menuPanel, final JScrollPane scrollPane, final JPanel resultPanel) { 2 JButton but1 = new JButton("提交"); 3 JPanel tfPanel1 = new JPanel(); 4 final JTextField tf1 = new JTextField(" "); 5 tfPanel1.setLayout(new BorderLayout(5, 0)); 6 tfPanel1.add(new JLabel("请输入题目数量:"), BorderLayout.WEST); 7 tfPanel1.add(tf1, BorderLayout.CENTER); 8 9 JPanel tfPanel2 = new JPanel(); 10 final JTextField tf2 = new JTextField(" "); 11 tfPanel2.setLayout(new BorderLayout(5, 0)); 12 tfPanel2.add(new JLabel("请输入操作数的最大值:"), BorderLayout.WEST); 13 tfPanel2.add(tf2, BorderLayout.CENTER); 14 15 JPanel tfPanel3 = new JPanel(); 16 final JTextField tf3 = new JTextField(" "); 17 tfPanel3.setLayout(new BorderLayout(5, 0)); 18 tfPanel3.add(new JLabel("是否有乘除(1为是,0为否):"), BorderLayout.WEST); 19 tfPanel3.add(tf3, BorderLayout.CENTER);
3.计算算数符优先顺序
1 public static void priority (int m){ 2 int counter = 0; //乘除计数器 3 int c = 0; 4 for(int h = 0;h<m;h++){ 5 if(counter == 0){ 6 if(yunsuan.get(h).equals("x")||yunsuan.get(h).equals("÷")){ 7 if(h == 0){ 8 priorityTemp [h] =h; 9 } 10 else if(h ==1){ 11 c = priorityTemp[0]; 12 priorityTemp[0] = h; 13 priorityTemp[h] = c; 14 } 15 //将a冒泡到第一个位置 16 else{ 17 priorityTemp[h] = priorityTemp[1]; 18 priorityTemp[1] = priorityTemp[0]; 19 priorityTemp[0] = h; 20 } 21 counter ++; 22 } 23 else{ 24 priorityTemp[h] = h; 25 } 26 } 27 else if(counter ==1){ 28 if(yunsuan.get(h).equals("x")||yunsuan.get(h).equals("÷")){ 29 if(h == 1){ 30 priorityTemp[h] = h; 31 }
五.模块接口部分的性能改进:
我们用JProfiler做的效能分析:
匆匆忙忙地完成作业,未能有充裕时间优化性能,深表遗憾~~
六.模块部分单元测试展示:
单元测试的覆盖率截图:这一部分是我的队友测试的,他用jacoco测试覆盖率的。
将程序运行后得到下面的代码覆盖率图:
代码的指令覆盖率达到了97%,但是因为我们用了很多if语句,所以分支覆盖率降到了81%。
七.模块部分异常处理说明:
我们没有设计异常目标。。。
八.界面模块的详细设计过程:
考虑到界面模块设计方面,我们主要是先将设置布局管理器,将界面的布局确定好。
1 // 设置布局管理器 2 setLayout(new BorderLayout(15, 15)); 3 4 JPanel menuPanel = new JPanel(); 5 JScrollPane scrollPane = new JScrollPane(); 6 JPanel resultPanel = new JPanel(); 7 8 jlTime.setForeground(Color.blue); 9 10 timer = new Timer(1000, new ActionListener() { 11 public void actionPerformed(ActionEvent e) { 12 Date now2 = new Date(now.getTime() + 1000); 13 now = now2; 14 SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); 15 jlTime.setText("耗时:" + formatter.format(now)); 16 } 17 }); 18 19 resultPanel.setVisible(false); 20 addContToMenu(menuPanel, scrollPane, resultPanel); 21 addContToResult(resultPanel); 22 23 this.add(menuPanel, BorderLayout.NORTH); 24 this.add(scrollPane, BorderLayout.CENTER); 25 this.add(resultPanel, BorderLayout.SOUTH); 26 27 }
将题目数量和其他判断条件加入菜单面板,包括输入题目数量等等。
1 // 将控件加入菜单面板 2 private void addContToMenu(JPanel menuPanel, final JScrollPane scrollPane, final JPanel resultPanel) { 3 JButton but1 = new JButton("提交"); 4 JPanel tfPanel1 = new JPanel(); 5 final JTextField tf1 = new JTextField(" "); 6 tfPanel1.setLayout(new BorderLayout(5, 0)); 7 tfPanel1.add(new JLabel("请输入题目数量:"), BorderLayout.WEST); 8 tfPanel1.add(tf1, BorderLayout.CENTER); 9 10 JPanel tfPanel2 = new JPanel(); 11 final JTextField tf2 = new JTextField(" "); 12 tfPanel2.setLayout(new BorderLayout(5, 0)); 13 tfPanel2.add(new JLabel("请输入操作数的最大值:"), BorderLayout.WEST); 14 tfPanel2.add(tf2, BorderLayout.CENTER); 15 16 JPanel tfPanel3 = new JPanel(); 17 final JTextField tf3 = new JTextField(" "); 18 tfPanel3.setLayout(new BorderLayout(5, 0)); 19 tfPanel3.add(new JLabel("是否有乘除(1为是,0为否):"), BorderLayout.WEST); 20 tfPanel3.add(tf3, BorderLayout.CENTER);
设置监听按钮,提交按钮做了三件事:时间暂停,计算本次正确率,计算总的正确率,在按提交键之后将题目输入到界面并开始计时。
1 // 设置按钮监听,按钮主要做这几件事:1.开始计时 2.调用mainExp类生成题目,3.结果面板设为可见,4.数据初始化 2 but1.addActionListener(new ActionListener() { 3 public void actionPerformed(ActionEvent arg0) { 4 clearAll(); 5 now.setHours(0); 6 now.setMinutes(0); 7 now.setSeconds(0); 8 timer.start(); 9 // 获得生成的题目list,赋给question的list中 10 mainExp createExercise = new mainExp(); 11 createExercise.createEquation(Integer.parseInt(tf1.getText().trim()), 12 Integer.parseInt(tf2.getText().trim()),Integer.parseInt(tf3.getText().trim())); 13 Command.this.setQuestion(createExercise.getQuestion()); 14 Command.this.setAnswer(createExercise.getAnswer()); 15 Command.this.addContToMain(scrollPane); 16 resultPanel.setVisible(true); 17 resultPanel.validate(); 18 19 } 20 }); 21 menuPanel.add(tfPanel1); 22 menuPanel.add(tfPanel2); 23 menuPanel.add(tfPanel3); 24 menuPanel.add(but1); 25 menuPanel.add(jlTime); 26 27 }
九.界面模块与计算模块的对接:
如何让界面模块与计算模块二者之间对接呢?我们主要的想法是可以通过生成gui界面,用户可以根据自己的要求输入想要的条件,然后后台接受到数据,生成算式并传送到界面,以下是图片展示:
十.描述结对的过程及其图片展示:
1.结对过程
我们的结对主要分为两个阶段,前一阶段主要是对主要框架的构思和对模块,界面等等的思考与设计阶段,并且参考与学习必要运用的那些知识,以及对项目作业要求的仔细阅读与审查,讨论哪些方面可以被实现,哪些方面可以实现的更好。第二阶段主要是分工负责各个部分的代码主要实现,对于命名规则等等,一开始没有统一,造成了麻烦,后来在沟通之下才最终意见一致,由于做的比较晚,比较匆忙,有一些本来设计中的没有实现,有些遗憾,细节处理的并不是很细致,但对我们来说已经殊为不易了。
2.结对照片展示
十一.说明结对编程的优点和缺点:
1.结对编程的优缺点
优点:是一次很好的团队合作的过程,从各个方面锻炼了两个人的合作以及两人的沟通交流能力。两个人之间可以相互交流学习,并且互相启发灵感,从而互相取长补短。在后期阶段共同完成项目时,充分地体现了1+1大于2的作用,顺利的完成任务。
缺点:前期磕磕绊绊,互相不熟悉,因此犯错频繁,极大地拖延了项目完成的时间。两个人初时沟通可能存在一些问题,对对方的想法理解的不好,导致了自己代码方面的一些错误,之后花了不少时间去纠正。
2.个人优点
郑书鸿 优点:(1)耐心,对于问题出现是先去解决,而不是拖延。
(2)比较专注,能够静下心来解决一些使人烦躁的问题。
(3)做自己力所能及的事情,比较有责任心。
缺点:编程能力不高,对模块化和界面设计等内容不怎么了解,往往花费大量时间在查看代码错误上。
师浩然 优点:(1)对java学习能力强,对于不会的内容看过几遍就掌握了。
(2)编程熟练度较高,对java知识理解深,能够实现项目主要要求。
(3)看问题比较透彻,能抓住项目要求中的一些关键要点并且对其有较强的执行力。
缺点:代码规范方面还存在一些问题,不够规范。
十二.PSP图(完成后):
PSP |
任务内容 |
计划共完成需要的时间 |
实际完成需要的时间 |
Planning |
计划 |
一周 |
一周 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
一周 |
一周 |
Development |
开发 |
4天 |
4天 |
Analysis |
需求分析 (包括学习新技术) |
3.5(h) |
3(h) |
Design Spec |
生成设计文档 |
2(h) |
2(h) |
Design Review |
设计复审 (和同事审核设计文档) |
1(h) |
1(h) |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
1(h) |
40min |
Design |
具体设计 |
1h |
35min |
Coding |
具体编码 |
2天 |
2天 |
Code Review |
代码复审 |
1(h) |
1(h) |
Test |
测试(自我测试,修改代码,提交修改) |
2(h) |
2(h) |
Reporting |
报告 |
2h |
1.5h |
Test Report |
测试报告 |
1.5h |
1h |
Size Measurement |
计算工作量 |
30min |
30min |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
30min |
20min |