2016012084结对作业项目报告

仓库:https://git.coding.net/librarian1/Operation_Generation_Validate.git
网站:http://ali.hellowood.com.cn:8089/ 出题做题都能实现,如果生成题目数量较多,会有一点延迟
队友:马越 http://www.cnblogs.com/mayue-/p/8768455.html

目录

  • 需求分析
  • 接口设计方法
  • 计算模块
    • 计算模块接口设计与实现
    • 计算模块接口性能改进
    • 计算模块单元测试
    • 计算模块异常处理说明
  • 界面模块
    • 界面模块设计
    • 界面与计算模块对接
  • 结对
    • 结对过程
    • 结点优缺点
  • PSP展示

需求分析

带界面四则运算出题网页程序

  • 基本功能:
    定制出题要求:
    -n题目数量范围1 ~ 10000
    -m [lower] [upper] 设定题目数值的范围(包括原始题目与运算过程中所有中间结果的绝对值的数值范围)下界参数范围为 1到100,上界参数范围为 50到1000
    -o题目中最多有多少个运算符,默认为1,范围1 ~ 10,除非指定运为1,否则每个算式运算符大于等于2
    -c题目中是否包含乘除法
    -b题目中是否包含括号
    运算过程中不得出现小数,可以出现负数。
    生成result.txt

  • 做题功能:
    不包括分数,但可能会出现负数与括号
    在后台解析题目;
    将题目挨个顺序展示,让用户答题;
    用户答题结束后,软件可统计本次用户的答题时长与答对题目的数量。

  • 附加功能
    计时器

接口设计方法

Information Hiding信息隐藏

1972年,David Parnas 发表了一篇题为《论将系统分解为模块的准则》的论文首次让公众注意到信息隐藏这一概念。
信息隐藏式结构程序设计与面向对象设计的基础之一。在面向对象设计中,它又引出了封装和模块化的概念,并与抽象的概念紧密相关。
in Parnas's seminal 1972 paper On the Criteria to Be Used in Decomposing Systems into Modules, this dictum is expressed in terms of information hiding, and the terms cohesion and coupling are not used. 来自维基百科

这是论文on the criteria to be used in decomposing systems into modules summary的英文PDF
下载

信息隐藏是软件的首要技术使命中格外重要的一种启发式方法,因为它强调的就是隐藏复杂度。

loose coupling 松耦合

在电脑运算和系统设计中,一个松耦合的系统中的每一个组件对其他独立组件的定义所知甚少或一无所知。子范围包括类、接口、数据和服务之间的耦合。

做法:
将出题功能与做题功能设计为2个类;
为每一个具体的出题参数设计一个接口,在生成题目的generation类中实现这些接口,并且对这个类进行封装;
在设计中不写入具体数字,而是设计常量;
避免循环调用,每一个类的方法都尽量封闭,不需要互相调用。
实现松耦合,接口可以由具体类generation和validate直接实现,而不需要改变依赖类interface,使得软件设计具有可扩展性

计算模块

计算模块接口设计与实现

关键算法:

  • 做题算法

  • 出题算法
    生成算子算符 —— 算结果并判断合法——生成算式(加括号)——输出

如何使用调度场算法

  1. 先随机生成一串算子(整数)和一串算符(按算符参数要求),存入两个链表

算子:A B C D
算符:x y z

  1. 算结果并判断合法
    整数加减乘除,有优先级
    逐步计算出结果,一旦过程出现分母为零或小数,则跳出

A x B y C z D

注意:这其中会出现A + B * C从左至右的运算,但之后输出算式会是(A + B)* C

  1. 生成算式(加括号)
    整数加减乘除
    设置2个整型priority1 ,priority2 对算子串中前后两个算子进行优先级判断,+-为低优先级0,×/为高优先级1。
    如果priority1 ,priority2 为 01 那么在两端加括号,否则00 10 11则不加。

计算模块接口性能改进

计算模块单元测试

用Junit4对generation类和validate类中每一个方法进行单元测试,因为是第一次写单元测试,所以一开始简直毫无头绪,后来决定用简单的assert断言来编写测试,并且遵照了一部分单元测试的原则,即

Right. 结果是否正确.

Boundary. 主要是CORRECT 原则

Independent. 一个测试应只专注于一个函数,或一组函数.

  • validate类中doResult方法的单元测试
    覆盖率:100%

  • generation类中operation,operator,character,bracket方法的单元测试

  • operator类

  • operation类

计算模块异常处理说明

对于题目数量,数值范围,运算符数量和题目要求输入等四个接口分别设计了异常。
异常写在了枚举类enum里面,然后在页面输入那些题目要求的时候会对每个输入框进行判断,如果有异常会走后台的方法输出异常

  • EXCEPTION_TITEL_NUMBER
    未设置题目数量或题目数量不符合规定
  • EXCEPTION_NUMBER_RANGE
    未设置数值范围或数值范围不符合规定
  • EXCEPTION_SIGN_NUMBER
    未设置运算符数量或运算符数量不符合规定
  • EXCEPTION_SIGN_NUMBER
    题目要求未提交

界面模块

我负责的是后端计算模块的设计,命令行的实现和单元测试,界面模块由马越同学负责。

界面模块设计

  • 定制做题

  • 计时器和展示题目

  • 判断对错和记录

  • 展示正确答案

界面与计算模块对接

两个servlet

  • GenerationServlet类 ——负责出题做题
    用表单将前台的参数传给generation类。然后生成String类型的字符串传给servlet,在servlet中写入的文件。
  • UploadServlet类 ——负责解析做题

结对

结对过程

结对优缺点

  • 缺点
    付出了两个人的努力却只得到了一个人的生产力,在刚刚开始结对编程时的确如此,两个同学都各自写各自的代码,最后还要将对方的代码再看一遍。
    刚开始结对时,对于自己的设计都会更加自信,类似“如果我自己做速度会更快”,特别是后期如果出现什么BUG,就会加大这种分歧。
  • 优点,
    我负责后端算法,马越负责前端界面,两个不同领域的人可以互补学习,能产出更优秀的代码。
    两人还能够从相互的交流中受益,通常能写出更加高效的代码。

队友互评
马越:

  • 做事果断,行动力强
  • 比较浮躁 无法集中注意力
    我(唐祎琳):
  • 喜欢思考比较有挑战的问题,不畏惧难题
  • 不喜欢求助

PSP展示

任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
计划 5 5
· 估计这个任务需要多少时间,并规划大致工作步骤 5 5
开发 782 1175
· 需求分析 (包括学习新技术) 60 90
· 生成设计文档 10 10
· 设计复审 (和同事审核设计文档) 2 5
· 代码规范 (为目前的开发制定合适的规范) 2 2
· 具体设计 60 90
· 具体编码 480 540
· 代码复审 30 60
· 测试(自我测试,修改代码,提交修改) 120 180
报告 55 37
· 测试报告 40 30
· 计算工作量 5 2
· 事后总结, 并提出过程改进计划 10 5

总结与改进

对于这一次的项目,是在单纯的写程序的基础上加上了测试和异常,还有用户界面的实现,这些都是我以前不感兴趣的内容,我总觉的过于简单了,不如算法有趣,但是实践才发现并非如此,其实测试也需要优秀的代码和思考,异常需要全面的考虑,界面需要有审美与用户体验的关注。

posted @ 2018-04-10 01:41  librarian1  阅读(257)  评论(2编辑  收藏  举报