结对作业:小学四则运算练习

小组成员:茅梓军 张航

一、项目地址:

  Coding.net git地址:https://git.coding.net/zhh1011/QuestionWeb.git

  线上版本:http://140.143.62.245:8080/QuestionWeb/

二、PSP(1):

PSP

任务内容

计划共完成需要的时间(h)

Planning

计划

4

 Estimate

 估计这个任务需要多少时间,并规划大致工作步骤

 4

Development

开发

 26

Test

测试

 2

Algorithm Optimization

算法优化

Interface Design

接口设计

Coding Standard

代码规范

Design

具体设计

Coding

具体编码

12 

Code Review

代码复审

Test

测试

Reporting

报告

Test Report

测试报告

0.5 

Size Measurement

计算工作量

0.5 

Postmortem & Process Improvement Plan

事后总结, 并提出过程改进计划

三、接口设计

这里主要涉及到信息隐藏,接口设计和松耦合这三个概念,首先我对于这三个概念的的认识比较模糊,所以我上网查找了有关知识:

1)Information hiding 信息隐藏:信息隐藏技术(Information Hiding),也就是信息隐藏,将在未来网络中保护信息不受破坏方面起到重要作用,信息隐藏是把机密信息隐藏在大量信息中不让对手发觉的一种方法。信息隐藏的方法主要有隐写术数字水印技术可视密码、潜信道、隐匿协议等。

2)interface 接口设计:软件的接口设计元素描述了信息如何流入和流出系统以及被定义为体系结构一份的构件之间是如何通信的。这次作业需要用到各种设计构建之间的内部接口,从俄日是的整个体系内的各个部分能通信与协作。

3)losing coupling 松耦合:松耦合系统通常是基于消息的系统,此时客户端远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。只要消息符合协商的架构,则客户端或服务的实现就可以根据需要进行更改,而不必担心会破坏对方。松耦合通讯机制提供了紧耦合机制所没有的许多优点,并且它们有助于降低客户端远程服务之间的依赖性。但是,紧耦合性通常可以提供性能好处,便于在客户端和服务之间进行更为紧密的集成(这在存在安全性和事务处理要求时,可能是必需的)

我们小组在达成一致意见之前我个人觉得应该从命令行程序出发,使用servlet在调用该程序,再结合上次作业的程序接口,将两者连接起来,就可以比较简单的实现初步的命令行程序。

四、编程过程(我们小组将计算模块接口的设计与实现过程与计算模块接口部分的性能改进合并到了一点)

  这次的设计与上次的差别不大(详情请看上次个人作业博客:http://www.cnblogs.com/zanghh/p/8641725.html),有所改变的地方是为了web开发设计的Servlet类ServletQuestion,与为了封装传递数据而设计的CommandE类(为了不与Command类重名),以及改进的命令行输出Command类。具体对比如下图:

  另外也对文件结构进行了调整(main包变成了com.hang包)

  因为在上次的代码中没有实现括号的生成和运算,Maker类(制造运算题)与Tester类(运算类)进行了大的改进。甚至为了计算括号从而产生了新的类Tools类(工具类,用于拆解括号运算)。以及为了在网页上进行数据传输的用于读取文件的Reader类,最后是用于计算由用户上传的运算题的UploadQuestion类(起名混乱了...)。在整个编码过程中尽量细分每个类的功能,例如在Tester类中计算的只是单纯的运算式(不包含括号),而括号与运算式的拆解由Tools类的splitList方法来完成的,在调试的过程中只需要不断的对Tools类进行修改,就可以利用原本的Tester类完成支持带括号的运算。至于Information Hiding,Interface Desig,Loose Coupling我想从下面的这一行代码讲起:

  在这里,首先是Command类自己的静态方法catchCommand处理传入的命令集,并将命令集转换为一个CommandE对象返还给Outer对象的构造器,Outer对象在自己构造器里调用Maker对象(同时也将自己的CommandE传给Maker对象),而Maker对象调用Tester对象对生成的Question对象进行判断(是否可用)(在这里Maker也将CommandE传递给了Tester对象以进行运算范围的限定),Tester在遇见含有括号Question对象调用Tools对象进行处理。最终一个可用的Question对象产生,利用其本身的toString()方法转换成String类型。将所有的Question最终又通过Outer对象的构造器调用自己的私有outQuestion方法输出成文件。

五、计算模块部分单元测试展示

  我在计算模块里大量调用了List的indexof()方法,这是整个模块里最消耗时间的一部分(在递归时被大量调用,在无法产生可用的Question时这一现象会更加严重)。优化的方法就是尽量使用变量去替换原本调用方法的部分。减少方法的调用,利用自定义异常在计算刚开始就结束那些明显无法产出的Question对象,节省计算时间。最终也算改进了一点性能吧。(效能分析还没有完善,暂时不放图了)

  单元测试测试了Maker、Tester与Outer(三大核心功能):

  

  设置模拟的数据输入,判断是否得到预期的结果,并尽可能的尝试代码中大多数的可能性,以便达到测试目的。

六、计算模块部分异常处理说明

  我们小组在本次项目中只设置了一个异常MyException,通过它和其他Java自有的异常来达到预期功能。例如catchCommand()方法中用到的:

  MyExcepton可以灵活的用来应对很多场景,例如需要判断所输入的字符数是否符合要求。而Java自有的异常更多的是方便的辨别一些特殊情况并来提示用户采取正确的做法。

有关MyException的一个应用

  有关MyException的测试涉及过广,所以并没有设置一个具体的方法来测试(从刚开始的命令输入到最后的网页输出都有它的身影),所以大多的测试是直接在Worker包下Test类中利用代码直接测试(大部分还留在那里)。

七、界面模块的详细设计过程

       这一部分能说的比较多,由于大一到现在我一直在学前端,刚好我的队友是学习后端的,所以这次作业刚好我负责前端界面,他负责后端连接与维护,花了大概一周的时间才完成了整个程序。

       这里我要着重讲一下我前端页面的编写历程,首先我从题目本身需求出发,觉得应该生成三个页面,分别是出题界面,答题界面和批改结果显示界面,在页面布局上,我觉得应该采用简洁的风格,因为使用者大致都是小学生,如果界面太过复杂就会降低用户体验,并采用蓝色吸引用户,下面是我所有页面的介绍。

       1)出题界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="create.css" rel="stylesheet" type="text/css" />
    <title>生成页面</title>
</head>
<body>
    <div class="title">小学四则运算练习题生成器</div>
    <div class="first">
        <div class="second">
            <span>请输入想要生成的题目数量:</span>
            <input type="text" name="">
        </div>
        <div class="third">
            <span>请选定算式数值范围:</span>
            <input type="text" name=""><input type="text" name="">
        </div>
        <div class="fouth">
            <span>请输入想要的运算符个数:</span>
            <input type="text" name="">
        </div>
        <div class="fifth">
            <span>题目中是否允许出现乘除法:</span>
            <input type="radio" name="1" value="male">允许
            <input type="radio" name="1" value="male">不允许
        </div>
        <div class="sixth">
            <span>题目中是否允许出现括号:</span>
            <input type="radio" name="2" value="yes">允许
            <input type="radio" name="2" value="no">不允许
        </div>
            <input type="submit" value="生成" class="seventh">
        </div>
</body>
</html>

2)答题界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>练习页面</title>
    <link href="do.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="title">小学四则运算练习题答题器</div>
    <div>
        <table class="box">
            <tr>
                <td>题目</td>
                <td>答案</td>
            </tr>
            <tr>
                <td>14+12-10=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>3*6-2+13=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>32+5*2-2=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>(13+5)*3=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>12/4+12=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>12+16-3*2=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>25/(3+2)+2=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>(3*6-12)/2=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
            <tr>
                <td>32/(4*2)+12=</td>
                <td>
                    <input type="text" name="">
                </td>
            </tr>
        </table>
    </div>
    </div>
        <input type="submit" value="批改" class="submit">
    </div>
</body>
</html>

3)批改界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>结果页面</title>
    <link href="result.css" rel="stylesheet" type="text/css">
</head>
<body>
    <div class="title">小学四则运算练习题批改结果</div>
    <div>
        <table class="box">
            <tr>
                <td>题目</td>
                <td>你的答案</td>
                <td>结果</td>
                <td>正确答案</td>
            </tr>
            <tr>
                <td>14+12-10=</td>
                <td>16</td>
                <td></td>
                <td>16</td>
            </tr>
            <tr>
                <td>3*6-2+13=</td>
                <td>29</td>
                <td></td>
                <td>29</td>
            </tr>
            <tr>
                <td>32+5*2-2=</td>
                <td>38</td>
                <td>×</td>
                <td>40</td>
            </tr>
            <tr>
                <td>(13+5)*3=</td>
                <td>54</td>
                <td></td>
                <td>54</td>
            </tr>
            <tr>
                <td>12/4+12=</td>
                <td>16</td>
                <td>×</td>
                <td>15</td>
            </tr>
            <tr>
                <td>12+16-3*2=</td>
                <td>22</td>
                <td></td>
                <td>22</td>
            </tr>
            <tr>
                <td>25/(3+2)+2=</td>
                <td>7</td>
                <td></td>
                <td>7</td>
            </tr>
            <tr>
                <td>(3*6-12)/2=</td>
                <td>3</td>
                <td></td>
                <td>3</td>
            </tr>
            <tr>
                <td>32/(4*2)+12=</td>
                <td>16</td>
                <td></td>
                <td>16</td>
            </tr>
        </table>
    </div>
</body>
</html>

       因为我们两个都是单独完成的前后端,所以在最后前后端合并的时候,删改了很多内容,页面有了很大的改动,但我并不觉得可惜,想到自己从大一加入工作室到现在,前端的技术越来越弱,这次作业算是给我了我巩固提升的机会,虽然最后没怎么用上,但这个过程已经很具有意义了。

八、界面模块与计算模块的对接

       用于处理前台跳转数据部分截图:

       WebContent是位于config包下一个用于存储.jsp文件路径的类

       因为需要一道题一道题的向用户展示,所以会将很多信息临时存放在Sesston里,两个listQuestion就成了接力赛中传递接力棒的运动员。

       请求也只是在它俩手里转了一圈而已

  download的方法类似,在这里就不展开描述了。

  ServletQuestion类实际上与计算模块的联系并不像想象的多,因为很难将用户上传的题目转换并封装成Tester模块所能接受的Question类,所以我们小组调用了JS中的eval方法来快捷的计算用户上传题目的答案,省去了调度场算法和逆波兰表达式,整个程序简单了很多。

 

       用于产生文件的Outer类

       用于计算答案是否正确的uploadQuestion类

  整个Servlet Question类与前端的对接则是充满setAttribute与getAttribute,以及在后台从Session中向前台传递信息,并没有很大的难点,但由于在页面跳转上太过于急躁,导致我们小组的前端页面样式崩溃,无法显示,最后的页面是这样的:

九、结对总结

       我和我的队友一致认为一个人的力量终归是有限的,或许可以在一个方面大放异彩,但在你不熟悉的领域,真的是寸步难行。比如我一个学习前端的,也许在页面设计上能做的很好,但是在后端连接服务器方面就几乎什么都不懂,而我的队友后端知识储备很足,但是一不小心也导致了前端页面崩溃,所以说一个人再强大也终归是一个人,项目开发是一个团队合作的过程,这也慢慢体现出了结对的优点:

       1.结对编程就是两个程序员互相审查的过程,在编程过程中能够尽早发现问题并解决问题,提高了编程效率。

  2.编程过程中遇到瓶颈两个人相互鼓励,极大的提高了编程的积极性。

  3.两个人在编程过程中不断磨合,相互学习,使双方的代码能力得到了一定程度上的增强,同时也有了合作意识。

       但结对形式也会有不足的地方,因为结对是多人的合作,中间难免会有思想的碰撞,从一方面看思维碰撞有利于大家思维的开拓,但另一方面也会引起争论,并浪费一定时间与精力去化解矛盾,但总的来说,我觉得结对形式还是利大于弊的。

       

 

       我的优点:

    遇到bug有耐心解决;

    注重细节,努力;

    努力学习弥补不足;

       我的缺点:

    编程经验不足,对程序把握不够;

       张航的优点:

    编程能力强;

    对于模块独立化有独特的见解;

    逻辑思维能力强,编程严谨;

       张航的缺点:

    不够细心,经常会忽略一些细节,考虑不够全面;

十、PSP(2)

PSP

任务内容

实际时间(h )

Planning

计划

5

 Estimate

 估计这个任务需要多少时间,并规划大致工作步骤

5

Development

开发

38

Test

测试

3

Algorithm Optimization

算法优化

4

Interface Design

接口设计

4

Coding Standard

代码规范

0

Design

具体设计

5

Coding

具体编码

15

Code Review

代码复审

3

Test

测试

4

Reporting

报告

4

Test Report

测试报告

0

Size Measurement

计算工作量

0.5

Postmortem & Process Improvement Plan

事后总结, 并提出过程改进计划

3.5

 

posted @ 2018-04-10 08:43  全网最帅  阅读(283)  评论(3编辑  收藏  举报