4. 请大家先在实验楼中的~/Code目录中用自己的学号建立一个目录,代码和UML图要放到这个目录中,截图中没有学号的会要求重做,然后跟着下面的步骤练习。
实验报告中统计自己的PSP(Personal Software Process)时间
步骤 |
耗时 |
百分比 |
需求分析 |
1h |
30 |
设计 |
2h |
40 |
代码实现 |
30mins |
10 |
测试 |
30mins |
10 |
分析总结 |
30mins |
10 |
编程是智力活动,不是打字,编程前要把干什么、如何干想清楚才能把程序写对、写好。与目前不少同学一说编程就打开编辑器写代码不同,我希望同学们养成一个习惯,当你们想用程序解决问题时,要会写三种码:
我们通过一个例子说明如何写这三种代码。
需求:我们要在一个MyUtil类中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。
1先写伪代码,用特定编程语言翻译一下,就是可用的产品代码了,当然,我们在这要选用Java.
2测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。这里我们的测试输入是“50”,预期结果是“不及格”。
3一般代码在边界处最容易出错,我们还没有测试边界情况,我们对输入为“0,60,70,80,90,100”这些边界情况进行测试,发现边界情况中输入100时有一个Bug。我们修改MyUtil.java,把判断优秀的条件中包含输入为100的情况。
(2) TDD(Test Driven Devlopment, 测试驱动开发)
基于TDD,我们不会出现过度设计的情况,需求通过测试用例表达出来了,我们的产品代码只要让测试通过就可以了。
1打开Eclipse,单击File->New->Java Project新建一个TDDDemo的Java项目
2在TDDDemo项目中,把鼠标放到项目名TDDDemo上,单击右键,在弹出的菜单中选定New->Source Folder新建一个测试目录test,
3把鼠标放到test目录上,单击右键,在弹出的菜单中选定New->JUnit Test Case新建一个测试用例类MyUtilTest
4在TDDDemo的src目录中新建一个MyUtil的类,并实现percentage2fivegrade方法,原因是MyUtil类还不存在,类中的percentage2fivegrade方法也不存在
5把鼠标放到MyUtilTest.java上,单击右键,选择Run as->JUnit Test
6出现了一个绿条(green bar),说明测试通过
(三)设计模式初步
(1)S.O.L.I.D原则
面向对象三要素是“封装、继承、多态”,任何面向对象编程语言都会在语法上支持这三要素。如何借助抽象思维用好三要素特别是多态还是非常困难的,S.O.L.I.D类设计原则是一个很好的指导。
(2)模式与设计模式
模式是某外在环境(Context) 下﹐对特定问题(Problem)的惯用解决之道(Solution)。模式必须使得问题明晰,阐明为什么用它来求解问题,以及在什么情况下有用,什么情况下不能起作用,每个模式因其重复性从而可被复用,本身有自己的名字,有可传授性,能移植到不同情景下。模式可以看作对一个问题可复用的专家级解决方法。 计算机科学中有很多模式:
GRASP模式
分析模式
软件体系结构模式
设计模式:创建型,结构型,行为型
管理模式: The Manager Pool 实现模式
界面设计交互模式
最重要的是设计模式,在面向对象中设计模式的地位可以和面向过程编程中的数据结构的地位相当。
(3)设计模式实示例
设计模式(design pattern)提供一个用于细化软件系统的子系统或组件,或它们之间的关系图,它描述通信组件的公共再现结构,通信组件可以解决特定语境中的一个设计问题。
(四)练习
1使用TDD的方式设计关实现复数类Complex。
//伪代码 //复数类 类有虚部实部 复数的加法运算 复数的减法运算 复数的乘法运算 复数的除法运算
//产品代码 public class ComplexDemo { // main方法 public static void main(String[] a) { Complex b = new Complex(2, 5); Complex c = new Complex(3, -4); System.out.println(b + "+" + c + "=" + b.add(c)); System.out.println(b + "-" + c + "=" + b.minus(c)); System.out.println(b + "*" + c + "=" + b.multiply(c)); System.out.println(b + "/" + c + "=" + b.divide(c)); } }
// Complex类 class Complex { private double m;// 实部 private double n;// 虚部
public Complex(double m, double n) { this.m = m; this.n = n; }
// add public Complex add(Complex c) { return new Complex(m + c.m, n + c.n); }
// minus public Complex minus(Complex c) { return new Complex(m - c.m, n - c.n); }
// multiply public Complex multiply(Complex c) { return new Complex(m * c.m - n * c.n, m * c.n + n * c.m); }
// divide public Complex divide(Complex c) { double d = Math.sqrt(c.m * c.m) + Math.sqrt(c.n * c.n); return new Complex((m * c.m + n * c.n) / d, Math.round((m * c.n - n * c.m) / d)); }
public String toString() { String rtr_str = ""; if (n > 0) rtr_str = "(" + m + "+" + n + "i" + ")"; if (n == 0) rtr_str = "(" + m + ")"; if (n < 0) rtr_str = "(" + m + n + "i" + ")"; return rtr_str; } } //测试代码
public static ComplexTest{ public static void main(String[] args){ class Complex {
private double m;// 实部 private double n;// 虚部
public Complex(double m, double n) { this.m = m; this.n = n; }
public String toString() { String rtr_str = ""; if (n > 0) rtr_str = "(" + m + "+" + n + "i" + ")"; if (n == 0) rtr_str = "(" + m + ")"; if (n < 0) rtr_str = "(" + m + n + "i" + ")"; return rtr_str; }
}
}
}
四.实验感想
这次实验比起实验一我觉得有难度多了,实验一的时候并没有在实验楼里面做,所以还不清楚使用的要求,在这次实验总算是进入实验楼了,刚开始用的时候不习惯,但用了之后发现其实很方便,这次实验虽然难,花了很多时间,但这样比起视频和课本能学到更多东西。
五.遇到的问题及解决方法
1.实验楼进去了但实验2点开没反应,求助老师之后发现是浏览器的问题,换了火狐之后就好了。
2.UML不知道在哪里打开,问了同学之后知道是点终端虚拟机,然后就出来了。