2017-2018-2 学号20165329 实验二《Java面向对象程序设计》实验报告
一、实验内容及步骤
(一)单元测试
(1)三种代码
- 举例:我们要在一个MyUtil类中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。
- 测试结果:
(2)TDD(Test Driven Devlopment, 测试驱动开发)
TDD的一般步骤:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过
- 循环完成所有功能的开发
- 基于TDD,我们不会出现过度设计的情况,需求通过测试用例表达出来了,我们的产品代码只要让测试通过就可以了。
TDD的编码节奏:
- 增加测试代码,JUnit出现红条
- 修改产品代码
- JUnit出现绿条,任务完成
- 测试结果:
(二)面向对象三要素
- 抽象
抽象一词的本意是指人在认识思维活动中对事物表象因素的舍弃和对本质因素的抽取。抽象是人类认识复杂事物和现象时经常使用的思维工具,抽象思维能力在程序设计中非常重要,"去粗取精、化繁为简、由表及里、异中求同"的抽象能力很大程度上决定了程序员的程序设计能力。
抽象就是抽出事物的本质特征而暂时不考虑他们的细节。对于复杂系统问题人们借助分层次抽象的方法进行问题求解;在抽象的最高层,可以使用问题环境的语言,以概括的方式叙述问题的解。在抽象的较低层,则采用过程化的方式进行描述。在描述问题解时,使用面向问题和面向实现的术语。
程序设计中,抽象包括两个方面:
过程抽象
数据抽象 - 封装、继承与多态
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。
面向对象的思想涉及到软件开发的各个方面,贯穿OOA、OOD和OOP的主线正是抽象:
面向对象分析(OOA):根据抽象关键的问题域来分解系统,关注是什么(what)
面向对象设计(OOD):是一种提供符号设计系统的面向对象的实现过程,用非常接近问题域术语的方法把系统构造成“现实世界”的对象,关注怎么做(how),通过模型来实现功能规范
面向对象编程实现(OOP):在设计的基础上用编程语言(如Java)编码
OOD中建模会用图形化的建模语言UML(Unified Modeling Language),UML是一种通用的建模语言,我们实验中使用umbrello进行建模,Windows中推荐大家使用 StarUML。
过程抽象的结果是函数,数据抽象的结果是抽象数据类型(Abstract Data Type,ADT),类可以作具有继承和多态机制的ADT。数据抽象才是OOP的核心和起源。
OO三要素的第一个要素是封装,封装就 是将数据与相关行为包装在一起以实现信息就隐藏。
封装实际上使用方法(method)将类的数据隐藏起来,控制用户对类的修改和访问数据的程度,从而带来模块化(Modularity)和信息隐藏(Information hiding)的好处;接口(interface)是封装的准确描述手段。
UML建模:
在UML 里,一个类的属性能显示它的名字,类型,初始化值,属性也可以显示private,public,protected。 类的方法能显示它们的方法名,参数,返回类型,以及方法的private,public,protected属性。其中:
+表示public
表示protected
-表示private
UML类图要展示类之间的静态关系,UML中依赖用带箭头的直线表示
UML类图中继承的表示法是用一个带三角的直线指向父类
继承指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用。既存类称作基类、超类、父类(base class、super class、parent class),新类称作派生类、继承类、子类(derived class、inherited class、child class)。继承关系表达了”Is a kind of“的关系,称为“ISA”关系。继承的关键在于确认子类为父类的一个特殊类型。
继承是实现软件可重用的根基,是提高软件系统的可扩展性与可维护性的主要途径。
以封装为基础,继承可以实现代码复用,需要注意的是,继承更重要的作用是实现多态。
面向对象中允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式,我们称此现象为多态性。Java中,多态是指不同的类对象调用同一个签名的成员方法时将执行不同代码的现象。多态是面向对象程序设计的灵活性和可扩展性的基础。
(三)设计模式初步
对设计模式示例进行扩充,体会OCP原则和DIP原则的应用,初步理解设计模式。让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
二、实验练习:使用TDD的方式设计关实现复数类Complex
- 必备知识
- 参考复数运算法则。
- 设计内容
- 伪代码
复数运算:
定义复数
定义构造函数
定义共有方法:加减乘除
- 产品代码
public class Complex{
private double r;
private double i;
public Complex(double r, double i) {
this.r = r;
this.i = i;
}
public static double getRealPart(double r) {
return r;
}
public static double getImagePart(double i) {
return i;
}
public Complex ComplexAdd(Complex a) {
return new Complex(r + a.r, i + a.i);
}
public Complex ComplexSub(Complex a) {
return new Complex(r - a.r, i - a.i);
}
public Complex ComplexMulti(Complex a) {
return new Complex(r * a.r - i * a.i, r * a.i + i * a.r);
}
public Complex ComplexDiv(Complex a) {
return new Complex((r * a.i + i * a.r)/(a.i * a.i + a.r * a.r), (i * a.i + r * a.r)/(a.i * a.i + a.r * a.r));
}
public String toString() {
String s = " ";
if (i > 0)
s = r + "+" + i + "i";
if (i == 0)
s = r + "";
if (i < 0)
s = r + " " + i + "i";
return s;
}
}
- 测试代码
三、总结与分析
我个人的感受而言,单元测试提供了一种高效快速的测试代码正确性的方法,可以对代码进行修复和完善,这样可以让我们的代码写的更好,更加完善,通过边界情况,正确情况的测试也能找出代码中不正确的地方。一开始不知道怎么做,参考了关于单元测试。自己有了很多思考,成长了许多。