结对编程

题目描述:

不知道大家是否尝试过这样一种开发模式:你有一个伙伴,你们坐在一起,并肩作战,面对着同一台显示器,使用着同一键盘,同一个鼠标,你们一起思考,一起分析,一起编程?这次,就让我们来体验一下结对编程的魅力:
http://www.cnblogs.com/xinz/archive/2011/08/07/2130332.html

我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序。进一步,本次要求把这个程序做成GUI(可以是Windows PC 上的,也可以是Mac、Linux,web,手机上的),成为一个有基本功能、一定价值的程序。在下面的功能需求中实现两个:

  1. 记录用户的对错总数,程序退出再启动的时候,能把以前的对错数量保存并在此基础上增量计算。
  2. 有计时功能,能显示用户开始答题后的消耗时间。
  3. 界面支持中文简体/中文繁体/英语,用户可以选择一种;

从题目要求中我们选择了1和2两个功能,即实现记录用户对错题数和计时功能。

 

码市地址:https://coding.net/u/lzx84/p/Calculation/git

一、队员组成以及分工情况

队员有: 201421123062(林燕)    201421123084(林至贤)

实现记录用户的对错题数由林至贤完成,我(林燕)实现显示用户开始答题后的消耗时间。整体的一起讨论完成。

编程过程使用了QQ的屏幕共享,一个人写的时候,另一个人在观看,并通过语音互相交流想法。

 

需求分析(新功能):

  1. 记录用户的对错总数,程序退出再启动的时候,能把以前的对错数量保存并在此基础上增量计算。(使用session存放统计对象列表的方法,一个对象相当于一次操作(感觉应该使用cookie,可是做了好久没法实现))
  2. 有计时功能,能显示用户开始答题后的消耗时间。(使用js的计时代码,使用获取两次系统时间相见计算用时。(因为JS不怎么熟,不怎么懂得用JS获取具体用时))
  3. 界面支持中文简体/中文繁体/英语,用户可以选择一种;(未实现)

二、程序设计过程

我们讨论了两个人的第一次四则运算的代码,考虑到我之前的代码没有很好地封装对象,便决定用至贤的第一次成果来做基础,在他之前的基础上改进,增加了一个新的对象,以便于后面的统计。我们用了jsp来写页面,一共设计了四个页面,具体看图:

新增类:

流程:

 

 

 

 

三、核心代码展示

 index.jsp:

复制代码
 1 <%@ page language="java" import="java.util.*"
 2     contentType="text/html; charset=UTF-8"%>
 3 <html>
 4 
 5 <head>
 6 <meta http-equiv="Content-Language" content="zh-cn">
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>提交</title>
 9 </head>
10 
11 <body
12     style="background-image: url('images/background.jpg');background-position: center;">
13     <p></p>
14     <p align="center">
15         <font face="华文彩云" size="7">四则运算器</font>
16     </p>
17     <form method="POST" action="show.jsp">
18         <p align="center">
19             请输入需要的题目数量:<input name="n" type="text" onkeyup="this.value=this.value.replace(/\D/g,'')" 
20             onafterpaste="this.value=this.value.replace(/\D/g,'')" /> <!--规定用户只能输入数字-->
21             
22              <input type="submit" value="确认"
23                 name="B1">
24         </p>
25 
26     </form>
27     <P align="center"><a href="showHistory.jsp">查看历史成绩</a></P>
28 
29 
30 
31     
32 </body>
33 
34 </html>
复制代码

show.jsp:

复制代码
  1 <%@page import="model.*" import="methods.*"%>
  2 <%@page language="java" import="java.util.*"
  3     contentType="text/html; charset=UTF-8"%>
  4 <%
  5     String path = request.getContextPath();
  6     String basePath = request.getScheme() + "://"
  7             + request.getServerName() + ":" + request.getServerPort()
  8             + path + "/";
  9 %>
 10 
 11 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 12 <html>
 13 <head>
 14 <base href="<%=basePath%>">
 15 
 16 <title>My JSP 'show.jsp' starting page</title>
 17 
 18 <meta http-equiv="pragma" content="no-cache">
 19 <meta http-equiv="cache-control" content="no-cache">
 20 <meta http-equiv="expires" content="0">
 21 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 22 <meta http-equiv="description" content="This is my page">
 23 <!--
 24     <link rel="stylesheet" type="text/css" href="styles.css">
 25     -->
 26 
 27 </head>
 28 
 29 <body>
 30 <div align="center" >
 31     <form method="POST" action="showResult.jsp"><%
 32         
 33         int op = 0;
 34         int n = Integer.parseInt(request.getParameter("n"));
 35         ArrayList<Fraction> resultlist = new ArrayList<Fraction>();//创建结果列表,存放答案
 36         ArrayList<String> titlelist = new ArrayList<String>();//创建题目列表,存放题目
 37         String title = "";
 38         for (int i = 1; i <= n; i++) {
 39             Fraction f1 = Dofrac.CreatFrac();
 40             Fraction f2 = Dofrac.CreatFrac();
 41             op = (int) (Math.random() * 4 + 1);
 42             Fraction result = new Fraction();
 43     %><div>
 44         <p>
 45             <%
 46                 switch (op) {
 47                     case 1: {
 48                         result = Calculate.add(f1, f2);
 49                         title = "第" + i + "题:" + f1.toString() + "+"
 50                                 + f2.toString() + "=";
 51                         out.println(title);
 52                         break;
 53 
 54                     }
 55                     case 2: {
 56                         if (!Calculate.compare(f1, f2)) {
 57                             Fraction temp = f1;
 58                             f1 = f2;
 59                             f2 = temp;
 60                         }
 61                         result = Calculate.sub(f1, f2);
 62                         title = "第" + i + "题:" + f1.toString() + "-"
 63                                 + f2.toString() + "=";
 64                         out.println(title);
 65                         break;
 66                     }
 67                     case 3: {
 68                         result = Calculate.mul(f1, f2);
 69                         title = "第" + i + "题:" + f1.toString() + "*"
 70                                 + f2.toString() + "=";
 71                         out.println(title);
 72                         break;
 73                     }
 74                     case 4: {
 75                         if (f2.getFenzi() == 0) {
 76                             f2.setFenzi((int) (1 + Math.random() * (10 - 1 + 1)));
 77                         }
 78                         result = Calculate.div(f1, f2);
 79                         title = "第" + i + "题:" + f1.toString() + "÷"
 80                                 + f2.toString() + "=";
 81                         out.println(title);
 82                         break;
 83                     }
 84                     }
 85                     resultlist.add(result);
 86                     titlelist.add(title);
 87                     
 88                     
 89         
 90                         
 91             %>
 92             <input type="text" name="s<%out.print(i);%>" size="20"
 93              style="width: 38px;">
 94              <input type="hidden" name="time" value=<%=System.currentTimeMillis() %>
 95              style="width: 38px;"><!--获得系统时间-->
 96         
 97 
 98         </p>
 99 
100     </div>
101     <%
102         }
103     %>
104     <input type="submit"  value="提交">
105     </form>
106 </div>
107     <%
108         session.setAttribute("n", n);
109         session.setAttribute("resultlist", resultlist);
110         session.setAttribute("titlelist", titlelist);
111         //将用户输入的n值,结果列表与题目列表存入session
112     %>
113     <div align="center" id="showTimes"></div>
114     <%
115         long current_time = 0;
116     %>
117     <script>
118         var second =
119     <%=current_time / 1000%>
120         ; //秒数
121 
122         // 写一个方法,将秒数转换为分钟以及小时
123         var toMinites = function() {
124             var s = second % 60;
125             var mi = (second - s) / 60 % 60; // 分钟
126             var h = ((second - s) / 60 - mi) / 60 % 24; // 小时
127             return h + ":" + mi + ":" + s;
128         }
129         function getTime() {
130             return toMinites;
131         }
132 
133         //计时器
134         window.setInterval(function() {
135             second++;
136             document.getElementById("showTimes").innerHTML = toMinites();
137         }, 1000);
138     </script>
139 </body>
140 </html>
复制代码

showResult.jsp:

复制代码
<%@page import="org.apache.taglibs.standard.tag.common.core.ForEachSupport"%>
<%@page import="model.*" import="methods.*"%>
<%@page language="java" import="java.util.*"
    contentType="text/html; charset=UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'show2.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

</head>

<body>
    <%
        long nowTime = System.currentTimeMillis();//得到用户做完题目之后的时间
        ArrayList<Fraction> resultlist = (ArrayList<Fraction>) session.getAttribute("resultlist");
        int n = (Integer) session.getAttribute("n");
        ArrayList<String> titlelist = (ArrayList<String>) session.getAttribute("titlelist");
        //从session中得到需要的数据
        String input;
        int flag=0;//错题数
        String time=(nowTime-Long.parseLong(request.getParameter("time")))/1000+"秒";//将两个时间相减,得到用时
        Fraction result = new Fraction();
        ArrayList<String> wrongList = new ArrayList<String>();//新建错题集
        Statistics st = new Statistics();
        

        

        for (int i = 1; i <= n; i++) {
    %>
    <p>
        <%
                out.print(titlelist.get(i - 1));
                input = (String) request.getParameter("s" + i);
                if (Dofrac.check(input)) {
                    out.print("  (你的答案是:" + input+")");
                } else {
                    out.print("(非法输入,答案作废)");

                }

                result = resultlist.get(i - 1);
                if (input.equals(result.toString())) {
                    out.print("————恭喜你!回答正确");

                } else {
                    out.print("————回答错误,正确答案是:" + result.toString());
                    flag++;
                    wrongList.add(titlelist.get(i - 1)); 
                    

                }
            }
        %>
    </p>
    <hr>
    <p>
    <%
        String acciracy=(n-flag+0.0)/n*100+"%";//计算正确率
        out.print("你作对了"+(n-flag)+"题,做错了"+flag+"题,正确率为:"+acciracy+",用时为:"+time);
        st.setAcciracy(acciracy);
        st.setTime(time);
        st.setWrongNum(flag);
        st.setWrongTitle(wrongList);
        ArrayList<Statistics> stList =((ArrayList<Statistics>)session.getAttribute("stList")==null)?new ArrayList<Statistics>():(ArrayList<Statistics>)session.getAttribute("stList");
        stList.add(st);
        session.setAttribute("stList", stList);
        //新建或从session中取得Statistic列表,将此次计算的statistics对象存入。(感觉这里用cookie更合适,不过不会用。。)
    %>
     </p>
     <a href="index.jsp">再做一次</a>

</body>
</html>
复制代码

showHistory.jsp

复制代码
 1 <%@page import="model.*" import="methods.*"%>
 2 <%@page language="java" import="java.util.*"
 3     contentType="text/html; charset=UTF-8"%>
 4 <%
 5     String path = request.getContextPath();
 6     String basePath = request.getScheme() + "://"
 7             + request.getServerName() + ":" + request.getServerPort()
 8             + path + "/";
 9 %>
10 
11 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
12 <html>
13 <head>
14 <base href="<%=basePath%>">
15 
16 <title>My JSP 'show3.jsp' starting page</title>
17 
18 <meta http-equiv="pragma" content="no-cache">
19 <meta http-equiv="cache-control" content="no-cache">
20 <meta http-equiv="expires" content="0">
21 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
22 <meta http-equiv="description" content="This is my page">
23 <!--
24     <link rel="stylesheet" type="text/css" href="styles.css">
25     -->
26 
27 </head>
28 
29 <body>
30 
31     <input type="button" value="返回上一级" onclick="javascript:history.back();">
32     <br>
33     <br>
34     <div align="center">
35         <%
36             ArrayList<Statistics> stList = (ArrayList<Statistics>) session
37                     .getAttribute("stList");//获取session中的statistics列表。遍历输出。
38             if (stList == null) {
39                 out.print("没有记录");
40             } else {
41                 for (int i = 0; i < stList.size(); i++) {
42         %>
43         <div>
44             <%
45             out.print("第"+(i+1)+"次做题:");
46             
47         %><br>
48             <%
49             out.print("---------------------------------------------------");
50             
51         %><br>
52 
53             <%
54             out.print("错题数:" + stList.get(i).getWrongNum());
55         %><br>
56             <%
57             out.print("用时:" + stList.get(i).getTime());
58         %><br>
59             <%
60             out.print("正确率:" + stList.get(i).getAcciracy());
61         %><br>
62             <%
63             out.print("错题:");
64         %><br>
65             <%
66             for (int j = 0; j < stList.get(i).getWrongTitle().size(); j++) {
67                         out.print(stList.get(i).getWrongTitle().get(j));
68         %><br>
69             <%
70             }
71         %><br>
72             <%
73             out.print("---------------------------------------------------");
74             
75         %><br>
76         </div>
77 
78         <%
79         }
80         }
81     %>
82     </div>
83 </body>
84 </html>
复制代码

 

四、程序展示

 做题演示:

 

 

 功能一(存取用户做题数据)演示:

 

PSP:

PSP2.1

Personal Software Process Stages

Estimated Time (h)

RealTime(h)

Planning

计划

 

 

· Estimate

估计这个任务需要多少时间

 

 

Development

开发

8

9

· Analysis

需求分析 (包括学习新技术)

1

2

· Design Spec

生成设计文档

0.5

0.5

· Design Review

设计复审

0.5

0.5

· Coding Standard

代码规范

1

0.5

· Design

具体设计

2

2.5

· Coding

具体编码

2

2

· Code Review

代码复审

0.5

0.5

· Test

测试(自我测试,修改代码,提交修改)

0.5

0.5

Reporting

报告

0.5

0.5

·

测试报告

 

 

·

计算工作量

 

 

·

并提出过程改进计划

 

 

五、小结感受

1、结对感受

  • 这次结对编程合作的还不错,因为之前课程设计已经合作过一次,不懂的东西一起讨论解决,配合的还可以。刚开始实现界面的时候,首先讨论的是用NetBeans还是Web,由于之前的java以及数据库可设都有涉及到jsp,所以便一致认为用jsp来写。接下来就是整体架构的问题了,讨论了是否用servlet以及整个存储结构用什么等。随后便开始了具体的编程,过程中我发现自己的编程能力和学习新技能的能力都想对比较弱,能感受到队友的力量比较强大,1+1还是大于2的,有的时候一个小错误,还有想的不周到之处可以由队友发现,假如没有队友就可能要花费很多时间和精力来处理。
  • 结对编程的过程中我更像驾驶员,由于编程基础比较弱,总是有着这样或者那样的小错误;至贤充当着领航员的角色,把握整体架构,饥饿的时候给我一块面包,走错方向了及时互相拉回来。感谢队友辛苦地指导我,让我体会到结对编程的力量,两个人刚开始的时候也有着这样活着那样的不同想法,就命名来说,我就是要驼峰式的命名方式,但是他可能没那么大要求,觉得那样麻烦,但最终慢慢磨合也得到了一致的结果。
  • 不论是团队还是结对,听取队友的意见非常重要,我们要学会如何与他人合作,避免一意孤行或者整个过程都不提任何想法。

2、过程中遇到的困难

在编程过程中遇到的问题都是先百度的,有时候一个小问题要解决很久,比如在用git Import项目到eclipse里面的时候遇到了问题,百度了挺久,参考了下面两篇文章:http://blog.csdn.net/dongchengrong/article/details/56833173    

http://blog.csdn.net/hil2000/article/details/8566456

在做动态显示计时的功能时没多大想法,百度了一下用window.setInterval();调用了计时器。过程中出现了时间显示上的乱码,最后问了一些人才解决。

下次要提高查找问题答案的速度,提高动手能力。

posted @ 2017-03-15 11:59  Lynn_LinYan  阅读(284)  评论(1编辑  收藏  举报