四则运算项目报告
一、代码仓库Coding.Net项目地址:https://git.coding.net/yanglq/Twork3.git
二、PSP展示:
PSP | 任务内容 | 计划共完成需要的时间(h) | 实际完成需要的时间(h) |
Planning | 计划 | 5 | 10 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 2 | 1.5 |
Development | 开发 | 65 | 104 |
Analysis | 需求分析(包括学习新技术) | 10 | 15 |
Design Spec | 生成设计文档 | 0.5 | 0.5 |
Design Review | 设计复审(和同事审核设计文档) | 5 | 6 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 0.5 | 0.5 |
Design | 具体设计 | 10 | 9 |
Coding | 具体编码 | 24 | 50 |
Code Review | 代码复审 | 5 | 8 |
Test | 测试(自我测试,修改代码,提交修改) | 10 | 15 |
Reporting | 报告 | 3 | 4 |
Test Report | 测试报告 | 1 | 2 |
Size Measurement | 计算工作量 | 1 | 1 |
Postmortem&Process Improvement Plan | 事后总结,并提出过程改进计划 | 1 | 1 |
三、关于接口设计
(1)Interface Design
接口(Interface)是一种与类相识的结构,只包含常量和抽象方法,它的目的是指明多个对象的共同行为。由于我们的程序用到的是Java,故Java接口的定义为:
修饰符 interface 接口名{
/** 声明常量 **/
/** 方法签名 **/
}
Java接口的实现:
修饰符 class 类名 [extends 父类名] [implement 接口列表]{
}
类和接口之间的关系成为接口继承(interface inheritance),接口继承和类继承本质上是相同的,简称为继承。在类继承中只能被单重继承,而实现接口时,一次可实现多个接口,每个接口之间用逗号隔开。implements关键字是一个类实现一个接口所用的关键字,它是用来实现接口中定义的抽象方法,实现一个接口,必须实现接口中的所有方法
Comparable接口定义:package java.lang;
pablic interface Comparable{
public int comparaTo(Object o);
}
comparaTo方法判断这个对象相对于给定对象o的顺序,并且当这个对象小于、等于或大于给定对象时,分别返回负整数、0和正整数。
ActionListener(事件监听器)接口包含处理事件的actionPerformed方法,监听器必须覆盖该方法来响应事件。
一个对象要成为源对象上动作时间的监听器,需满足两个条件:①这个对象必须是ActionListener接口的一个实例,该接口定义了所有动作监听器共有的动作;②ActionListener对象listener必须使用方法source.addActionListener(listener)注册给源对象
Cloneable接口定义:package java.lang;
public interface Coneable{
}
这个接口是空的,一个带空体的接口称为标记接口(market interface),一个标记接口既不包括常量也不包括方法,它用来表示一个类拥有某些特定的属性。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用Object类定义的clone()方法克隆
参考自:《Java语言程序设计·基础篇》Y.Daniel Liang(阿姆斯特朗兰大州立大学)著、李娜(西安电子科技大学)译
(2)Information Hiding
信息隐藏是指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。
假设A打算秘密传递一些信息给B,A需要从一个随机消息源中随机选取一个无关紧要的消息C,当这个消息公开传递时,不会引起人们的怀疑,称这个消息为载体对象(Cover Message)C;把秘密信息(Secret Message)M隐藏到载体对象C中,此时,载体对象就变成了伪装对象C1.载体对象C是正常的,不会引起人们的怀疑,伪装对象C1与载体对象C无论从感官(比如感受图像、视频的视觉和感受声音、音频的听觉)上,还是从计算机的分析上,都不可能把他们区分开来,而且对伪装对象C1的正常处理,不应破坏隐藏的秘密信息。这样就实现了信息的隐藏传输。秘密信息的嵌入过程可能需要密钥,也可能不需要密钥,为了区别于加密的密钥,信息隐藏的密钥称为伪装密钥k。信息隐藏涉及两个算法:信息嵌入算法和信息提取算法,如下图:
参考自:百度百科
(3)Loose Coupling
模块设计追求强内聚、弱耦合。内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量,耦合(Coupling)是模块之间依赖程度的度量,内聚和耦合是密切相关的
内聚类型有:偶然内聚、逻辑内聚、时间内聚、过程内聚、通信内聚、顺序内聚、功能内聚(内聚强度由低到高)
耦合的强度依赖于以下几个因素:一个模块对另一个模块的调用;一个模块向另一个模块传递的数据量;一个模块施加到另一个模块的控制的多少;模块之间的接口程度
耦合类型有:内容耦合、公共耦合、控制耦合、标记耦合、数据耦合、非直接耦合(耦合强度由强到弱)
弱耦合一般使用数据耦合。模块间通过参数传递基本类型的数据,称为数据耦合。
参考自博客:http://www.cnblogs.com/jarod99/
四、计算模块接口的设计与实现过程
①程序界面设计
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>四则运算练习小程序</title> <style type="text/css"> body{ text-align:center; background-image:url(1.jpg); background-size:cover; background-attachment:fixed; background-position:center; background-repeat:no-repeat; } .p1{ font:italic; font-size:25px; font-family:Microsoft Yahei; margin-top:60px; } .submit{ font-size:18px; margin-top:60px; } </style> </head> <body> <h1 style="text-align:center">欢迎来到四则运算练习小程序!</h1> <p class="p1">在这里,你将巩固练习四则运算</p> <form method="get" action="Select.html" class="option"> <button class="submit" title="准备好了,请点击!" >你准备好了吗?</button> </form> </body> </html>
②题目定制界面设计
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>题目定制</title> <style type="text/css"> body{ background-image:url(1.jpg); background-size:cover; background-attachment:fixed; background-position:center; background-repeat:no-repeat; } </style> </head> <body> <h1 style="text-align:center;">题目定制</h1> <form method="get" action="Exercise.html" > <ol> <li> 请设定题目数量: <input type="text" name="number0" /> </li> <br/> <li> 请设定运算式中最小数值: <input type="text" name="number1" /> 最大数值: <input type="text" name="number2" /> </li> <br/> <li> 请设定最大运算符号数: 1<input type="radio" value="1" name="numberOfOperator" checked="checked" /> 2<input type="radio" value="2" name="numberOfOperator" /> 3<input type="radio" value="3" name="numberOfOperator" /> 4<input type="radio" value="4" name="numberOfOperator" /> 5<input type="radio" value="5" name="numberOfOperator" /> </li> <br/> <li> 请设定题目中是否有乘除法: 有 <input type="radio" value="Y" name="multiplyAndDivide" /> 没有 <input type="radio" value="N" name="multiplyAndDivide" checked="checked" /> </li> <br/> <li> 请设定四则运算式中是否有括号: 有 <input type="radio" value="Y" name="bracket" /> 没有 <input type="radio" value="N" name="bracket" checked="checked" /> </li> </ol> <input type="submit" title="填写好了,进行提交" value="提交" /> </form> </body> </html>
③练习四则运算界面设计
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>开始四则运算练习</title> <style type="text/css"> body{ text-align:center; background-image:url(1.jpg); background-size:cover; background-attachment:fixed; background-position:center; background-repeat:no-repeat; } </style> </head> <body> <h1>开始你的四则运算练习</h1> <iframe src="Exercise00.txt" width="85%" height="500" scrolling="auto">四则运算练习</iframe> <form method="get" action="Select.html" > <input type="submit" title="题目定制错误,返回上一步" value="返回上一步" /> </form> <form method="get" action="Answer.html" > <input type="submit" title="我做完了,我要验证答案!" value="提交" /> </form> </body> </html>
④验证答案界面设计
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>验证运算答案</title> <style type="text/css"> body{ text-align:center; background-image:url(1.jpg); background-size:cover; background-attachment:fixed; background-position:center; background-repeat:no-repeat; } .submit{ font-size:18px; margin-top:30px; } </style> </head> <body> <h1>验证你的运算答案</h1> <iframe src="Exercise00.txt" width="85%" height="500" scrolling="auto">四则运算练习</iframe> <form method="get" action="Select.html" class="option"> <button class="submit" title="扶我起来,我还能再战!" >返回题目定制</button> </form> </body> </html>
五、计算模块部分单元测试展示
@Test public void testDecide(){//测试控制整除的递归 int m=User.decide(10, 3); assertThat(m, is(5)); int n=User.decide(10, 1); assertThat(10%n, is(0)); }
@Test public void testIsOpe(){ assertThat(User.isOperator("5"), is(false)); assertThat(User.isOperator("+"), is(true)); assertThat(User.isOperator("-"), is(true)); assertThat(User.isOperator("*"), is(true)); assertThat(User.isOperator("÷"), is(true)); assertThat(User.isOperator("("), is(true)); assertThat(User.isOperator(")"), is(true)); }
@org.junit.Test public void testCore(){//测试产生随机式、中缀转后缀和计算后缀表达式 LinkedList<String> list=makeQuestion.expression(5, 0, 1, 2, 99); LinkedList<String> list1=makeQuestion.expression(10, 1, 0, 2, 99); Iterator<String> it=list.iterator(); StringBuilder sd=new StringBuilder(); while (it.hasNext()) { sd.append(it.next()).append(" "); } String[] ss=sd.toString().split(" "); Iterator<String> it1=list1.iterator(); StringBuilder sd1=new StringBuilder(); while (it1.hasNext()) { sd1.append(it1.next()).append(" "); } String[] ss1=sd1.toString().split(" "); makeQuestion.toSuffix("test.txt"); makeQuestion.dealEquation("test.txt"); makeQuestion.toSuffix("test.txt"); makeQuestion.dealEquation("test.txt"); }
@org
.junit.Testpublic
void
testIsOpe(){
assertThat(makeQuestion.isOperator("5"
), org.hamcrest.CoreMatchers.is(
false
));
assertThat(makeQuestion.isOperator("+"
), org.hamcrest.CoreMatchers.is(
true
));
assertThat(makeQuestion.isOperator("-"
), org.hamcrest.CoreMatchers.is(
true
));
assertThat(makeQuestion.isOperator("*"
), org.hamcrest.CoreMatchers.is(
true
));
assertThat(makeQuestion.isOperator("÷"
), org.hamcrest.CoreMatchers.is(
true
));
assertThat(makeQuestion.isOperator("("
), org.hamcrest.CoreMatchers.is(
true
));
assertThat(makeQuestion.isOperator(")"
), org.hamcrest.CoreMatchers.is(
true
));
}
六、异常处理说明
①User类异常处理:
②News类异常处理:
七、界面模块的设计过程
八、界面模块与计算模块的对接
①进入四则运算练习小程序:
②进行题目定制,设定题目的数量、运算式中最小数值及最大数值、最大运算符号数、是否有乘除法及括号等,如下图:
③在完成题目定制后,点击提交进入四则运算练习界面,在这里程序将给出定制数量的题目,提供用户练习;当用户定制题目意向出错时,可以点击返回上一步,重新进行题目定制,如下图:
④在完成四则运算练习后点击提交可来到验证页面,用户可以验证练习的正确与否,如下图:
九、结对的那些小事
在刚开始结对完成作业的时候,我们两个还比较迷茫,对于结对应该怎么做?怎样合作?都存在着些许疑问,但在阅读《构建之法》第四章之后便豁然开朗。首先我们对作业进行讨论并进行任务的分配,估计我们将在程序的各个模块的开发上耗费的时间并制作PSP表格;在完成作业的过程中,我们两个一起讨论、一起设计、一起编码、一起单元测试、一起编写文档等,具有非常强额解决问题的能力也提高了代码效率和质量。这是一个非常棒的体验!以下图片见证我们的pair:
十、关于结对编程
优点:
①可以每时每刻都处在代码复审的状态
②一对程序员可以平等地、互补地进行开发工作
③在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作能有更强的解决问题的能力
④对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带啦更高的满足感
⑤结对编程能相互督促,在心理上,能够更好地监督自身和更好地提高自身的技术能力
⑥在企业管理层次上,结对能更有效地交流,互相学习和传递经验,能更好地处理人员流动
⑦结对编程能得到更高的投入产出比(Return of Investment)
⑧结对编程在一定程度上避免了个人英雄主义,能够帮助建立集体拥有代码的意识
缺点:
①在高速度中完成任务,任务有较高的技术要求,任务失败的代价很高
②开发人员需要时间来适应这种新的开发模式,刚开始的结对编程效率可能不见得比单独开发效率高
③结对编程要求两个人协调一致,每个人的作息时间需要同步。当有一人出现情况另一人不得不等待
④结对编程不能像单独开发一样自主和自由
⑤结对编程中两个人的职责是相同的,可以减小每一个人的压力,但又容易造成缺乏责任感
结对中的你我:
YLQ:在这次结对作业中她连续几天熬夜查阅各种资料、学习知识来攻克这次的作业,非常地认真尽职,但因为遇到一些难题而变得比较焦躁,写代码时bug较多。总的来说她是个非常棒的结对partner。
ZST:这次结对作业过程中她能比较耐心地尽力完成每一部分,但同时也遇到非常多不懂的知识面,通过查阅各种资料并学习攻克。虽然她掌握的技能和知识较为匮乏,但能努力学习并补足,也是个值得结对的pair。