一、实验报告封面
课程:Java程序设计 班级:1752班 姓名:艾星言 学号:20175224
指导教师:娄嘉鹏 实验日期:2019年4月17日
实验时间:13:45 - 15:25 实验序号:24
实验名称:面向对象程序设计
实验内容
测试点一
- “测试驱动开发”(TDD)。TDD的一般步骤如下:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过(没产品代码呢)
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过(重构下次实验练习)
- 循环完成所有功能的开发
测试点二
public int capacity()
返回当前容量。容量指可用于最新插入字符的存储量,超过这一容量便需要再次分配。- 示例代码如下,使用TDD学习测试四个方法。
public class StringBufferDemo { public static void main(String [] args) { StringBuffer buffer = new StringBuffer(); buffer.append('S');//调用方法append,输入char型 buffer.append("tringBuffer");//调用方法append,输入String型 System.out.println(buffer.charAt(1));//t System.out.println(buffer.capacity());//返回buffer对象的容量:16 System.out.println(buffer.length());//返回buffer对象的长度:12 System.out.println(buffer.indexOf("tring"));//返回输入的子字符串的第一个字母在母字符串的位置。 System.out.println("buffer = " + buffer.toString()); } }
- 测试代码为:
import junit.framework.TestCase; import org.testng.annotations.Test; public class StringBufferDemoTest extends TestCase { StringBuffer a= new StringBuffer("String"); StringBuffer b = new StringBuffer("StringBuffer"); @Test public void testcharAt() throws Exception{ assertEquals('S',a.charAt(0)); assertEquals('g',a.charAt(5)); } @Test public void testcapacity() throws Exception{ assertEquals(22,a.capacity()); assertEquals(28,b.capacity()); } @Test public void testlength() throws Exception{ assertEquals(6,a.length()); assertEquals(12,b.length()); } @Test public void testindexOf() throws Exception{ assertEquals(0,a.indexOf("Str")); assertEquals(6,b.indexOf("Bu")); } }
测试点三
设计模式初步
- S.O.L.I.D原则
- SRP(Single ResponsibilityPrinciple,单一职责原则)
- OCP(Open-Closed Principle,开放-封闭原则)
- LSP(Liskov Substitusion Principle,Liskov替换原则)
- ISP(Interface Segregation Principle,接口分离原则)
- DIP(Dependency Inversion Principle,依赖倒置原则
- 设计原则:
- OCP原则:开放-封闭yuanze。其具体内容为:软件实体扩充开放,修改关闭。可以通过抽象和继承;面对接口编程。
- DIP原则:依赖倒置原则。其具体内容为:高层模版不应该依赖与底层模版,二者都应该依赖于抽象;抽象不应该依赖于细节,细节一个依赖与抽象。
- 设计模式有四个基本要素:
- Pattern name:描述模式,便于交流,存档
- Problem:描述何处应用该模式
- Solution:描述一个设计的组成元素,不针对特例
- Consequence:应用该模式的结果和权衡(trade-offs)
// Server Classes abstract class Data {//抽象一个类 abstract public void DisplayValue();//抽象方法,无返回。 } class Integer extends Data {//继承抽象类,重写方法 int value; Integer() { value=100; } public void DisplayValue(){ System.out.println (value); } } class byteteger extends Data { byte value; byteteger() { value=24; } public void DisplayValue() { System.out.println(value); } } // Pattern Classes abstract class Factory {//抽象一个类 abstract public Data CreateDataObject();//抽象方法,返回一个Date类创建的对象 } class IntFactory extends Factory {//继承抽象类,重写方法 public Data CreateDataObject(){//返回一个Integer类创建的对象 return new Integer(); } } class byteFactoey extends Factory { public Data CreateDataObject() { return new byteteger(); } } //Client classes class Document { Data pd; Document(Factory pf){ pd = pf.CreateDataObject(); } public void DisplayData(){ pd.DisplayValue(); } } //Test class public class MyDoc { static Document d; static Document b; public static void main(String[] args) { d = new Document(new IntFactory()); d.DisplayData(); b=new Document(new byteFactoey()); b.DisplayData(); } }
测试点四
- 提交:单元测试代码和运行成功截图及码云上代码链接,截图要加上学号水印
- 任务:以TDD的方式开发一个复数类Complex,要求如下:
// 定义属性并生成getter,setter double RealPart; double ImagePart; // 定义构造函数 public Complex() public Complex(double R,double I) //Override Object public boolean equals(Object obj) public String toString() // 定义公有方法:加减乘除 Complex ComplexAdd(Complex a) Complex ComplexSub(Complex a) Complex ComplexMulti(Complex a) Complex ComplexDiv(Complex a)
- TDD开发思路回顾:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过(没产品代码呢)
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过(重构下次实验练习)
- 循环完成所有功能的开发
- 复数的四则运算公式
- (a+bi)+(c+di)=(a+c)+(b+d)i
- (a+bi)-(c+di)=(a-c)+(b-d)i
- (a+bi)*(c+di)=(ac-bd)+(ad+bc)i
- (a+bi)/(c+di)=(a+bi)(c-di)/(c^2+d^2)
按照步骤:
- 测试代码为:
/*(1)属性:复数包含实部和虚部两个部分, double RealPart;复数的实部 double ImagePart;复数的虚部 getRealPart():返回复数的实部 getImagePart();返回复数的虚部 setRealPart():设置复数的实部 setImagePart();设置复数的虚部 输出形式:a+bi (2)方法: ①定义构造函数 public Complex() public Complex(double R,double I) ②定义公有方法:加减乘除 Complex ComplexAdd(Complex a):实现复数加法 Complex ComplexSub(Complex a):实现复数减法 Complex ComplexMulti(Complex a):实现复数乘法 Complex ComplexDiv(Complex a):实现复数除法 ③Override Object public String toString():将计算结果转化为字符串形式并输出*/ import junit.framework.TestCase; import org.testng.annotations.Test; public class ComplexTest extends TestCase { Complex c1=new Complex(1,1); Complex c2=new Complex(1,0); Complex c3=new Complex(0,1); Complex c4=new Complex(-1,-1); @Test public void testComplexAdd() { assertEquals("2.0+1.0i",c1.ComplexAdd(c2).toString()); assertEquals("1.0+1.0i",c2.ComplexAdd(c3).toString()); assertEquals("1.0+1.0i",c3.ComplexAdd(c2).toString()); assertEquals("0.0",c1.ComplexAdd(c4).toString()); } @Test public void testComplexSub() { assertEquals("1.0i",c1.ComplexSub(c2).toString()); assertEquals("1.0",c1.ComplexSub(c3).toString()); assertEquals("2.0+2.0i",c1.ComplexSub(c4).toString()); assertEquals("1.0-1.0i",c2.ComplexSub(c3).toString()); } @Test public void testComplexMulti() { assertEquals("1.0+1.0i",c1.ComplexMulti(c2).toString()); assertEquals("-1.0+1.0i",c1.ComplexMulti(c3).toString()); assertEquals("1.0i",c2.ComplexMulti(c3).toString()); assertEquals("-2.0i",c1.ComplexMulti(c4).toString()); } @Test public void testComplexDiv() { assertEquals("1.0+1.0i", c1.ComplexDiv(c2).toString()); assertEquals("1.0+1.0i", c1.ComplexDiv(c3).toString()); assertEquals("-1.0-1.0i", c1.ComplexDiv(c4).toString()); assertEquals("-0.5-0.5i", c2.ComplexDiv(c4).toString()); } }
- 产品代码为:
/*(1)属性:复数包含实部和虚部两个部分, double RealPart;复数的实部 double ImagePart;复数的虚部 getRealPart():返回复数的实部 getImagePart();返回复数的虚部 setRealPart():设置复数的实部 setImagePart();设置复数的虚部 输出形式:a+bi (2)方法: ①定义构造函数 public Complex() public Complex(double R,double I) ②定义公有方法:加减乘除 Complex ComplexAdd(Complex a):实现复数加法 Complex ComplexSub(Complex a):实现复数减法 Complex ComplexMulti(Complex a):实现复数乘法 Complex ComplexDiv(Complex a):实现复数除法 ③Override Object public String toString():将计算结果转化为字符串形式并输出 */ public class Complex { private double RealPart;//复数的实部 private double ImagePart;//复数的虚部 public Complex() {} public Complex(double a, double b) { setRealPart(a); setImagePart(b); } public void setRealPart(double a) { RealPart = a; } public void setImagePart(double b) { ImagePart = b; } public double getRealPart() {//返回复数的实部 return RealPart; } public double getImagePart() { return ImagePart; } Complex ComplexAdd(Complex a) {//(a+bi)+(c+di)=(a+c)+(b+d)i Complex complex = new Complex(); complex.RealPart = this.RealPart + a.RealPart; complex.ImagePart = this.ImagePart + a.ImagePart; return complex; } Complex ComplexSub(Complex a) {//(a+bi)-(c+di)=(a-c)+(b-d)i Complex complex=new Complex(); complex.RealPart=this.RealPart-a.RealPart; complex.ImagePart=this.ImagePart-a.ImagePart; return complex; } Complex ComplexMulti(Complex a) {//(a+bi)*(c+di)=(ac-bd)+(ad+bc)i Complex complex =new Complex(); complex.RealPart=this.RealPart*a.RealPart-this.ImagePart*a.ImagePart; complex.ImagePart=this.RealPart*a.ImagePart+this.ImagePart*a.RealPart; return complex; } Complex ComplexDiv(Complex a) {//(a+bi)/(c+di)=(a+bi)(c-di)/(c^2+d^2) Complex complex=new Complex(); complex.RealPart=(this.RealPart*a.ImagePart+this.ImagePart*a.RealPart)/(a.ImagePart*a.ImagePart+a.RealPart*a.RealPart); complex.ImagePart=(this.ImagePart*a.ImagePart+this.RealPart*a.RealPart)/(a.ImagePart*a.ImagePart+a.RealPart*a.RealPart); return complex; } public String toString() { if (ImagePart==0) { String str = String.valueOf(RealPart); return str; } else if (RealPart==0) { String str = String.valueOf(ImagePart)+"i"; return str; } else { if (ImagePart>0) { String str = String.valueOf(RealPart) + "+" + String.valueOf(ImagePart) + "i"; return str; } else { String str = String.valueOf(RealPart) + String.valueOf(ImagePart) + "i"; return str; } } } }
- 测试结果:
测试点五
- 检查点要求:使用WhiteStarUML对实验二中的代码进行建模,发类图的截图,加上学号水印。参考http://www.cnblogs.com/rocedu/p/6736847.html
- 类图中只少两个类。
实验中遇到的问题
1.增加MyUtil
的测试类之后,TestCase
是红色的,但是没有找到junit.jar
包的地方
解决方法:
- 找到电脑中IDEA安装路径
- 打开File->Project Structure
- 点击
Dependencies
,单击右上角的+,然后选择第一个JARs or directories
- 复制刚才的路径名,找到
junit-4.12 jar
、junit.jar
- 选择
junit-4.12 jar
、junit.jar
两项,并点击下方Ok
2.对于变量的使用,最开始没注意使用this关键字,运算出错。
解决方法:
- P84在实例方法中使用this:当this关键字出现在实例方法中时,this就代表正在调用该方法的当前对象
PSP
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 10min | 6% |
设计 | 20min | 11% |
代码实现 | 60min | 35% |
测试 | 30min | 18% |
分析总结 | 50min | 30% |