结对工程作业
像以往一样,先放上项目地址:
Coding.net git地址:https://git.coding.net/zhh1011/QuestionWeb.git
线上版本:http://140.143.62.245:8080/QuestionWeb/
二、PSP:
PSP |
任务内容 |
计划共完成需要的时间(h) |
Planning |
计划 |
4 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
4 |
Development |
开发 |
26 |
Test |
测试 |
2 |
Algorithm Optimization |
算法优化 |
2 |
Interface Design |
接口设计 |
2 |
Coding Standard |
代码规范 |
0 |
Design |
具体设计 |
2 |
Coding |
具体编码 |
12 |
Code Review |
代码复审 |
5 |
Test |
测试 |
5 |
Reporting |
报告 |
3 |
Test Report |
测试报告 |
0.5 |
Size Measurement |
计算工作量 |
0.5 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
2 |
三、编程过程:
这次的设计与上次的差别不大(详情请看上次个人作业博客: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类中利用代码直接测试(大部分还留在那里)。
六、界面模块设计:
个人处理的是整个项目的后端部分,在这里就只阐述我所负责的了。
整个页面的跳转过程:
index为主页,用于选择生成还是;
create顾名思义,用于生成题目;
download,下载生成题目,也可以跳转至doQuestion;
doQuestion,根据来路不同,让用户回答不同来源的题目(download来的回答生成的,upload来的回答上传的),中途也可终止答题;
result,列出全部问题,显示正确与否,同时也会列出用户答案与正确答案,若为中途结束则剩下题目在这里显示未作,并且可跳转回index;
error,整个过程中任何时间有异常发生都会跳转到该页面并显示异常提示,可返回index页面;
部分页面展示(在服务器端没了样式...):
用于处理前台跳转数据部分截图:
WebContent是位于config包下一个用于存储.jsp文件路径的类
值得一提的是两个listQuestion与doQuestion之间的跳转(download与upload各有一个用于跳转doQueston的方法,流程图中也有表现),因为需要一道题一道题的向用户展示,所以会将很多信息临时存放在Sesston里,两个listQuestion就成了接力赛中传递接力棒的运动员。
请求也只是在它俩手里转了一圈而已
download的方法类似,就不再放出了。
ServletQuestion类实际上与计算模块的联系并不像想象的多(毕竟一行代码就解决的事也牵扯不到太多东西...),因为很难将用户上传的题目转换并封装成Tester模块所能接受的Question类,所以我调用了JS中的eval方法来快捷的计算用户上传题目的答案,实际与运算模块有所联系可能就只有两三行代码了。
用于产生文件的Outer类
用于计算答案是否正确的uploadQuestion类(命名啊...)
整个Servlet Question类与前端的对接则是充满setAttribute与getAttribute,以及在后台从Session中向前台传递信息,并没有很大的难点(值得注意的是,因为转发请求式的跳转,我搞砸了搭档的前端样式)。
七、结对的感想
整个结对编程给人最大的感触就是一个人的力量终归是有限的,或许可以在一个方面大放异彩,但在你不熟悉的领域,真的是寸步难行。结对过程中因为大部分时间都是工作室中度过,当你有一个自己解决不了的难题时,闷头苦想,像没头苍蝇一样在网络上浪费时间,远远比不上开口问一句来的简单。而且结对过程中当你的思维被自己的定式局限时,另外的一个人可以从另一个角度将你从思维泥潭中拯救出来,这可比单人赴会节省了不少时间。但不过相对的,两个人思维的碰撞,说服彼此花费的时间也不比一个人苦思闷想浪费的时间少啊。
结对编程优点:
1.结对编程就是两个程序员互相审查的过程,在编程过程中能够尽早发现问题并解决问题,提高了编程效率。
2.编程过程中遇到瓶颈两个人相互鼓励,极大的提高了编程的积极性。
3.两个人在编程过程中不断磨合,相互学习,使双方的代码能力得到了一定程度上的增强,同时也有了合作意识。
结对编程缺点:
1.一个人独立钻研的时候,两个人思路会不同,编程方法也不同,需要时间来抉择用哪一个方法,需要磨合时间
张航的优点:
编程能力强;
对于模块独立化有独特的见解;
逻辑思维能力强,编程严谨;
张航的缺点:
不够细心,经常会忽略一些细节,考虑不够全面;
茅梓君的优点:
遇到bug有耐心解决;
注重细节,努力;
努力学习弥补不足;
茅梓君的缺点:
编程经验不足,对程序把握不够;
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 |