截止日期
2018年4月16日7:00
提交地址
https://github.com/eudaem/homework2
本次结对编程作业分为以下两种类型Core(计算核心)和UI(用户界面),每组任选一个完成,原则上两种类型题目各占一半
Core
像《构建之法》的人物阿超那样,写一个能自动生成小学四则运算题目并给出答案的命令行 “软件”, 如果我们要把这个功能放到不同的环境中去(例如,命令行,Windows 图形界面程序,网页程序,手机App),就会碰到困难,因为目前代码的普遍问题是代码都散落在main ( )函数或者其他子函数中,我们很难把这些功能完整地剥离出来,作为一个独立的模块满足不同的需求。
我们看到,不同的代码解决不同层面的问题,有些是内部数据的计算 (例如四则运算);有些是和用户输入相关的 (例如 scanf,cin,图形界面的输入字段),有些是和数据的展现相关的(例如 printf ,cout,println,DrawText),有些是和程序所在平台的架构相关的(例如 main 函数,并不是所有的程序都需要某个特定格式的main)。这就需要我们对软件的架构做一些整理和优化。
建议大家把四则运算的计算功能包装在一个模块中(这个模块可以是一个类 Class, 一个DLL,等等), 为了方便起见,我们叫它 “计算核心”Core 模块, 这个模块至少在两个地方可以使用:
- 测试程序,这个可以是一个命令行的程序,或者是JUnit 的框架,或者是Visual Studio 单元测试的框架。这样,我们在算法层级保证了这个模块的正确性。
- 实际的软件,这是交付给最终用户的软件,有一定的界面和必要的辅助功能。
那么这个Core模块和使用它的其他模块之间是什么关系呢?它们要通过一定的API (Application Programming Interface) 来和其他模块交流。这个API 接口应该怎么设计呢?
(这是一个需要有一定经验和实力的题目),为了简单,我们可以从下面的最简单的接口开始:
1.Calc()
这个Calc 函数接受字符串的输入(字符串里就是算术表达式,例如 “5*3.5”,“7/8 - 3/8 ”,“3 + 90 * 0.3”等等),这个模块的返回值是一个字符串,例如,前面几个例子的结果就是(“17.5”,“1/2”,“30”)。
如果输入是有错误的,例如 “1 ++ 2”, 在数值范围是 -1000 .. 1000 的时候,传进去“10000 + 32768”,或者是“248 / 0” 怎么办?怎么告诉函数的调用者“你错了”?把返回的字符串定义为“-1” 来表示? 那么如果真的计算结果是“-1”又怎么处理呢?
建议这个时候,我们要定义各种异常(Exception),让Core在碰到各种异常情况的时候,能告诉调用者——你错了!定义要增加的功能 - 例如:支持 “运算式子格式错误” 异常
2.Setting()
在生成四则运算题目之前,需要对一系列属性进行设置,例如生成题目的数量,操作数的数量,题目中操作数的数值的范围,运算符的种类,(+-*/,是否支持真分数运算,是否支持小数运算,是否支持乘方运算……
如果我想表示:
注:
题目中操作数的数值范围对于真分数来说是指其分母的范围,运算结果可以超出指定范围
当题目中包含小数时,答案亦以小数形式给出,结果为无限小数时保留小数点后两位
乘方运算的幂次方为小于5的自然数
怎么通过API 告诉我们的模块呢?我们当然可以用函数的参数直接传递,但是参数的组合很多,怎么定义好参数的规范呢?建议大家考虑用XML来传递这些参数。
3.Generate()
进行一些设置之后,就可以开始生成所需要的题目了,题目增加以下限制
例如1 - 2 + 3 =,3 + (4 - 5) =,因为计算过程中产生了负数,都是无效的题目
例如 1 + (2 * 3),(1 + 2)+ 3
其中括号为不必要的括号,不能生产此类题目
即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。
实现以上接口,编写API文档,供UI组使用(亦可自行增加功能)
以下是刘乾师兄当时的经验贴,大家可以作为参考
http://www.cnblogs.com/SivilTaram/p/4859934.html
UI
这是交付给最终用户的软件,有一定的界面和必要的辅助功能。完成Windows和Linux电脑图形界面的程序,需实现以下功能:
- 对上述各属性参数(生成题目的数量,操作数的数量,题目及答案中的数值的范围……)进行设置
- 调用Core模块得到题目和运算结果,显示题目,接受输入,并能判断答案是否正确
- 增加“倒计时”功能,每个题目必须在20秒内完成,否则,得0分并进入下一题
- 增加“错题记录”功能,对于答错的题,将其保存下来,当下次进行“复习”时,增大错题在练习题中的概率
- 增加”历史纪录“功能,把用户做题的成绩纪录下来并可以展现历史纪录
- 增加“成绩分享”功能,生成成绩单,想一想成绩单里要展现什么,仅仅是最后的得分吗?错题的类型及数量?帮用户分析其薄弱的环节,提出合理的学习建议?
……
UI组需对所有Core组的模块进行测试
项目管理
- 分析整理需求,完成PSP表格
- 使用Github进行代码管理
博客要求
1、两个人合起来写一份报告,发布到blog中,博客开始给出项目Github地址,但是需要注明,每一个阶段,驾驶员、领航员各自做的是什么工作。
2、仔细分析结对编程与上一次个人作业的差异
1)总结结对编程对这次作业的意义
2)从结对过程中,学到了什么
3、界面软件的细节,要写到blog中去
4、本次是两个人做作业,总的开发力量比上次多,所以blog中对每个阶段要写得更细
开发计划、时间规划、代码架构和设计、开发、调试、测试、发布等过程,什么地方体现了设计原则,例如单一职责原则,开放-封闭原则或者MVC架构等,给出PSP表格。
5、开发过程中碰到的bug要及时记录下来,仔细分析
1)为什么会出现这个bug?
2)这个bug是可以避免的吗?
3)调试这个bug用了多久,什么方法?
4)有什么教训值得吸收?
6、走上工作岗位后,是否选择结对编程用于解决部分任务?发表个人的看法
7、截止到4月12日,课程已经进行了40天了,对整个课程提出自己的看法和意见,也写到本次作业的末尾
8、今后的团队作业,每周的任务,准备如何吸收个人作业、结对作业,改善开发流程?
致谢
本次作业是在邹欣老师和刘乾师兄的建议下设计完成的,并且参考了罗杰老师的博客,在此,对他们的支持表示衷心的感谢!