结对项目

我的结对项目队友是

阿样


##coding.net 地址

四则运算实验室(四则运算网页版)


##在线测试的url

四则运算实验室(在线测试)
请多次打开这个网页,第一次加载可能比较慢,并且不会出现字体,影响效果
如果之前打开过网页,网页更新过,请先清除缓存后重新打开该网页



看教科书和其它资料中关于Information Hiding, Interface Design, Loose Coupling的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的。

  • Information Hiding
    • 类与类之间要相互利用私有变量时用定义的方法去调用获取私有变量,如get和set,可以很方便的访问变量。
    • 项目中我们要想使用类中的方法和变量,只需要调用此类即可,不需要知道这个类中的方法具体如何实现。但不可以随意对类中的方法进行修改,如果你想 要修改只需要对此类进行调用从而使用方法即可。简单来说,就是不需要知道具体实现方法,只要知道类的功能,直接调用即可。
  • Interface Design
    • 接口设计是功能的封装,在写程序之前想好接口要实现的全部功能,如果后来用户需求改变了,则可以直接改变实现接口的类。
    • 项目中我们模块划分主要分为计算模块,显示模块,控制模块(只要是用来链接显示模块与计算模块),对于计算模块,只需要调用其即可。
  • Loose Coupling
    • 松耦合,防止两个类之间交互性太强,改动一个会使另一个也有改动,可用接口连接两个类,使改动一个类的代码时不用担心会影响到另一个类。
    • 项目中我们并未对于两个类的交互进行过多的设计,也是调用方法就可以了。



计算模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。

  • 模块接口的设计

    • 四个类 产生题目,生成结果,选择文件,输出内容,写入文件
      • Writting类
      • inputFile类
      • Producing类
      • Command类
    • 十五个方法
  • 关键函数的流程图



计算模块接口部分的性能改进。记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图,并展示你程序中消耗最大的函数。



计算模块部分单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。只需要测试命令行部分,且该部分覆盖率到90%以上,否则单元测试部分视作无效。

  • 部分测试代码

    • command测试
    • inputFile类中inputFile测试
    • inputFile类中result测试
    • needing方法测试
    • arrayPractice测试
  • 命令行测试



计算模块部分异常处理说明。在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。

  • 输入参数异常处理

    •      if(args[r].equals("-n") ){
      
            try {
                n = Integer.parseInt(args[++r]);//命令行输入
                if (n<0||n>10000)
                    System.out.println("n必须输入正整数");
            }
            catch (Exception e)
            {
                System.out.println("n输入格式不正确");
            }
      
        }
        else  if(args[r].equals("-m")){
            try {
                lower= Integer.parseInt(args[++r]);
                upper= Integer.parseInt(args[++r]);
                if(lower>=upper){
                    System.out.println("lower不能大于等于upper");
                }
      
            }catch (Exception e){
                System.out.println("lower,upper,输入不合法");
            }
      
        }
      
        else   if(args[r].equals("-o")){
      
            try {
                opNum= Integer.parseInt(args[++r]);
                if (opNum>10||opNum<1)
                    System.out.println("opNum取值为1-10");
            }
            catch (Exception e)
            {
                System.out.println("opNum输入格式不正确");
            }
      
      
        }
      
  • 上传文件异常

    •    if (file.exists() && file.isFile()) {
        try {
            BufferedReader input = new BufferedReader(new FileReader(file));
            String text;
      
            while ((text = input.readLine()) != null)
                list.add(text);
            } catch (IOException ioException) {
                System.err.println("File Error!");
            }
        }
      
  • 写入文件异常

    •    try {
        BufferedWriter bw = new BufferedWriter(new FileWriter(path));
      
        for(String con:content){
            bw.write(con);
            bw.newLine();
        }
        bw.close();
      
  • 文件格式不正确

    •    System.out.println("测试获取文件的后缀:"+str);
           if(!(str.equals(".txt"))){
               PrintWriter out = response.getWriter();
               out.print("<script language='JavaScript'>alert('The file format is wrong!!');window.location.href='../upload.jsp';</script>");
           }
      



界面模块的详细设计过程。在博客中详细介绍界面模块是如何设计的,并写一些必要的代码说明解释实现过程。

  • 整体布局设计
    • 首页
    • 上传文件页面
    • 在线生成题目页面(生成后跳转到另一页面进行答题)
  • 各个页面共同的模块设计
    • 菜单栏 共同的logo,提供跳转页面的链接的导航
    • 底部的footer 作者的名字,提供联系的方式
    • 提示框 显示功能,提示页面的功能及相应的服务
  • 各个页面各自的模块设计
    • upload页面 上传文件页面,设置了上传文件的功能服务,上传后题目显示到页面并提供输入框,对于题目的读取设置了滚动条,方便快捷
      设置了界面适用于计时及得到正确数目
    • online页面 在线生成页面,提供了用户定制功能,并且能够进行前台的直接验证,提供跳转服务,生成题目后直接跳转到答题页面

######界面的设计

界面的设计主要由我来制作,我依照最简单的div+css布局,设计了一个能够通用的基本框架,进而在其中添加需要的元素,比如答题界面和计时及正确题目数 量模块,并且设计了简单的js代码实现计时功能、判断正确与否、正确数目及表单验证功能。并为其添加了符合四则运算使用者的界面效果,如提示的背景是黑板,整个页面的风格较为清新可爱,字体使用了外联新蒂黑板报及点点字体。

具体的界面样式依靠的是css的控制,最外围依靠的是body的像素固定大小,其余部分依靠的是百分比实现布局固定。

配色参考
图片来源
图标来源


######以下是写的较好的前台代码 表单验证
function check(form){

//验证题目数量
var quesNum = document.forms["online_choose"].elements["quesNum"].value;
var minNum = document.forms["online_choose"].elements["minNum"].value;
var maxNum = document.forms["online_choose"].elements["maxNum"].value;
var operScope = document.forms["online_choose"].elements["operScope"].value;
if(isNaN(quesNum)){
    alert("请输入题目数量,数量为0-10000");
    document.forms["online_choose"].elements["quesNum"].focus();
    return false;
}
if( quesNum == '' || quesNum < 0 || quesNum > 10000 ){
    alert("请输入题目数量,数量为0-10000");
    document.forms["online_choose"].elements["quesNum"].focus();
    return false;
}


if(isNaN(minNum)){
    alert("请输入正确的题目的数值最小值");
    document.forms["online_choose"].elements["minNum"].focus();
    return false;
}
if(minNum == '' || minNum < 0  || minNum > 100){
    alert("请输入题目数值最小值,0-100");
    document.forms["online_choose"].elements["minNum"].focus();
    return false;
}

if(isNaN(maxNum)){
    alert("请输入正确的题目数值最大值");
    document.forms["online_choose"].elements["maxNum"].focus();
    return false;
}
if(maxNum == '' || maxNum < 50  || maxNum > 1000){
    alert("请输入题目数值最大值,50-1000");
    document.forms["online_choose"].elements["maxNum"].focus();
    return false;
}

if(parseInt(minNum) >  parseInt(maxNum)){
    alert("请输入正确的范围,且最大值必须至少比最小值大50");
    document.forms["online_choose"].elements["minNum"].focus();
    document.forms["online_choose"].elements["maxNum"].focus();
    return false;
}

if(parseInt(maxNum) - parseInt(minNum) < 50 ){
    alert("请输入正确的范围,且最大值必须至少比最小值大50");
    document.forms["online_choose"].elements["minNum"].focus();
    document.forms["online_choose"].elements["maxNum"].focus();
    return false;
}

if(isNaN(operScope)){
    alert("请输入正确的参数值");
    document.forms["online_choose"].elements["operScope"].focus();
    return false;
}
if(operScope == '' || operScope < 0 || operScope > 10){
    alert("请输入运算符范围,否则默认为1,数值不能超过10");
    document.forms["online_choose"].elements["operScope"].focus();
    return false;
}


}

判断正误

    //判断是否回答正确
     function yesOrNo(){
     //yes 为题目正确个数
    //total为题目总个数&
    var yes=0;
    var total = document.getElementById("total_number").value;
    var get_answer = document.getElementsByClassName("get_answer");
    var yesOrNo = document.getElementsByClassName("gou");
    var right_answer= document.getElementsByName("meng");


    for(var i = 0; i < total ; i++){
        //传过来的答案right_answer
        //输入的答案get_answer
        //得到的题目get_ques&ndash;%&gt;

        if(get_answer[i].value == right_answer[i].value){
            yesOrNo[i].innerHTML="yes";
            yesOrNo[i].style.color="#ADFF99";
            yes++;
        }else{
            yesOrNo[i].innerHTML="no";
            yesOrNo[i].style.color="#FF9494";
        }
    }

    var yesNum = document.getElementById("right_number");
    yesNum.value = yes;
}

######界面设计部分 嵌套模式答题设计及计时功能
<div class="output">
        <div class="output_answer">

            <ul>
                <li>
                    题目
                </li>
                <li>
                    答案
                </li>
                <li>
                    对错
                </li>
            </ul>
            <div class="answer_scroll">
                <form   method="get">
                <table>

                        <%
                            String path = String.valueOf(request.getAttribute("path"));
                            int countR=0;
                            int countL=0;
                            InputFile inputFile=new InputFile();
                            List<String> s1=inputFile.InputFile(path);
                            String[] answer=new String[s1.size()];
                            for(int i=0;i<answer.length;i++){
                                //String ss=inputFile.result(s2);
                                answer[i]=(inputFile.result(s1.get(i)));
                            }
                            request.setAttribute("answer",answer);
                             %>
                    <input type="hidden" id="right_answer" value="<%=answer %>"/>
                    <%
                            for (String s:s1)
                            {
                        %>
                    <tr>
                        <td>
                           <%=s %>
                        </td>
                        <td>
                            <input type="text" name="answer" class="get_answer"/>
                        </td>
                        <td>
                            <span  class="gou">

                            </span>

                        </td>
                    </tr>
                        <%

                            } %>

                </table>
                </form>
            </div>
            <input type="submit" value="提交" id="aa" onclick="yesOrNo()"/>
        </div>
       <div class="output_judge">
            <div class="judge_clock">
                <button type="button" onclick="start()"><img src="img/play.png"/></button>
                <button type="button" onclick="stop()"><img src="img/stop.png"/></button>
                <button type="button" onclick="Reset()"><img src="img/over.png"/></button>
                <input type="text" id="timetext" value="00时00分00秒" readonly><br/>
            </div>
            <div class="judge_number">
                <ul>
                    <li>
                        <span>本次题目一共有</span>
                    </li>
                    <li>
                        <input type="text" id="total_number" value="<%=answer.length %>" READONLY/>
                    </li>
                    <li>
                        <span>正确的题目一共有</span>
                    </li>
                    <li>
                        <input type="text" id="right_number" READONLY/>
                    </li>
                </ul>
            </div>
        </div>



界面模块与计算模块的对接。详细地描述UI模块的设计与两个模块的对接,并在博客中截图实现的功能。


######UI模块的设计主要有一个输出的div,class名为output_answer,其下包括两个部分:
  • 描述各个列的名称,由ul表单实现,分别为题目、答案、对错

  • 输出题目的框,由于其具有滚动框的特性,我们对其命名为answer_scroll,使用循环输出使所有的题目都能展现,答完所有的题目后可以点击提交按钮,随即 进行验证,得到正确与错误的提示,在对错一列显示,红色表示错误,绿色表示正确,十分鲜明

  • 另外对于要求中的计时及正确答案,设置了一个div,具有float属性,名为output_judge,可以进行计时及输出正确答案

  • 定制功能为一个表单的提交,由我进行验证,得到的结果提交给计算模块并返回结果值

两个模块的对接
界面中加入一段jsp代码,其中引入一个list集合为题目,再引入一个数组为正确答案,同时在界面中获取题目总数并直接输出
使用jstl标签,使用<c:foreach>,其中放置一个隐藏的input来获取答案数组的值
直接在界面中循环输出题目,循环次数为获取的页面中total_number块的值
使用js代码获取用户输入的答案的值和正确答案的值进行对比,统计正确的题目数量
输出题目总数和正确的题目数量
定制部分主要实现为表单提交实现页面跳转,跳转至第二界面进行答题

######功能实现的截图 ![](https://images2018.cnblogs.com/blog/1344051/201804/1344051-20180409193833739-2117978738.jpg)



描述结对的过程,提供非摆拍的两人在讨论的结对照片。

结对的过程:

  1. 商讨项目的制作过程,包括使用的代码,技术规范,页面的框架,实现的功能等
  2. 计划分工及功能的实现,进行PSP的初期规划
  3. 正式开始进行项目的制作,计算模块与界面模块同时进行
  4. 进行页面的交互,并且同时不断修改代码
  5. 进行测试
  6. 发布项目
  7. 撰写博客



说明结对编程的优点和缺点。同时指出结对的每一个人的优点和缺点在哪里 (要列出至少三个优点和一个缺点)。

结对编程的优缺点
  • 优点
    • 能实时更新项目进度,交流密切,方便项目实施
    • 对于懒惰的一方有督促的作用
    • 集思广益,相同的问题两个人更好解决
    • 分工明确,减少工作量
  • 缺点
    • 对于两个人的配合有较高的要求
    • 对于两个人的时间和经历有较高的要求
    • 容易产生分歧
结对的每一个人的优缺点

刘卓锦

  • 优点
    • 代码能力强
    • 耐心
    • 细心
  • 缺点
    • 不爱写注释

翁梦蕾

  • 优点
    • 有设计风格
    • 细心
    • 耐心
  • 缺点
    • 对于java掌控不熟



附属的PSP表格



附上我觉得实在是好看的页面



总结

这次的作业基本上花去了我一个星期的时间,不停地修改,调试,整合。清明节的时候也没有休息,基本24小时14个小时都在做这个项目。可能会觉得收获到了什么,但我还是觉得付出大于收获。不知道是我的理解能力有问题还是某方面的问题,我总觉得这次的作业有些地方是描述不清的。结对项目貌似把所有的人都框死了,我为什么一定要两个人坐在一起敲代码,两个人有明确的分工难道不行吗。作为一个基本的项目必然是有分工的,在公司内也不可能所有人都是把所有事情一起做完,这样其实也是效率低下的表现。

##添加附加功能 【2018.05.06】 最后添加了附加功能,语言功能的支持 ![](https://images2018.cnblogs.com/blog/1344051/201805/1344051-20180506184312443-2097719401.jpg)

相关的设置,使用了cokie.js使页面跳转时维持语言的选择

原文地址:https://www.cnblogs.com/wowocandy-milk/p/8743073.html