2018-2019-2 20175211 实验二《Java面向对象程序设计》实验报告
代码托管
一、单元测试
(1)三种代码
以前写程序时没什么规范,都是想到哪写到哪,能一遍过简直就是中彩票了。但是编程指的不仅仅是敲代码的过程,最重要的是动手之前的思路要清晰,把干什么、如何干想清楚。写小程序的时候或许可以直接写,但是真的要做大项目的时候必须要会写三种代码
- 伪代码
- 产品代码
- 测试代码
需求:我们要在一个MyUtil类中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。
伪代码:
hundred-mark to five-point:
if grade less-than 60, convert to "不及格"
if grade between 60 and 70, convert to "及格"
if grade between 70 and 80, convert to "中等"
if grade between 80 and 90, convert to "良好"
if grade between 90 and 100, convert to "优秀"
else, convert to "错误"
产品代码:
public class MyUtil{
public static String percentage2fivegrade(int grade){
//如果成绩小于60,转成“不及格”
if (grade >= 0 && grade < 60) {
return "不及格";
}
//如果成绩在60与70之间,转成“及格”
else if (grade >= 60 && grade < 70) {
return "及格";
}
//如果成绩在70与80之间,转成“中等”
else if (grade >= 70 && grade < 80) {
return "中等";
}
//如果成绩在80与90之间,转成“良好”
else if (grade >= 80 && grade < 90) {
return "良好";
}
//如果成绩在90与100之间,转成“优秀”
else if (grade >= 90 && grade <= 100) {
return "优秀";
}
//其他,转成“错误”
else {
return "错误";
}
}
}
测试代码:
import org.junit.Test;
import 考察点1.MyUtil;
public class MyUtilTest extends TestCase {
@Test
public void testNormal(){
assertEquals("不及格", MyUtil.percentage2fivegrade(55));
assertEquals("及格",MyUtil.percentage2fivegrade(65));
assertEquals("中等",MyUtil.percentage2fivegrade(75));
assertEquals("良好",MyUtil.percentage2fivegrade(85));
assertEquals("优秀",MyUtil.percentage2fivegrade(95));
}
@Test
public void testException(){
assertEquals("错误",MyUtil.percentage2fivegrade(200));
assertEquals("错误",MyUtil.percentage2fivegrade(-10));
}
@Test
public void testBoundary(){
assertEquals("不及格",MyUtil.percentage2fivegrade(0));
assertEquals("及格",MyUtil.percentage2fivegrade(60));
assertEquals("中等",MyUtil.percentage2fivegrade(70));
assertEquals("良好",MyUtil.percentage2fivegrade(80));
assertEquals("优秀",MyUtil.percentage2fivegrade(90));
assertEquals("优秀",MyUtil.percentage2fivegrade(100));
}
}
使用Junit进行单元测试,分别测试正常、异常、边界三种情况,测试通过
二、TDD(Test Driven Development,测试驱动开发)
也是第一次听说写代码可以先写测试代码再写产品代码的,但是仔细想想其实差不多。我们每次写代码的时候都有个预期,希望实现什么样的功能,TDD只是把这个过程体现在测试代码里面。
以TDD的方式研究学习StringBuffer
测试代码
package 考察点2;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class StringBufferDemoTest {
StringBuffer str12 = new StringBuffer("hereare12chr");
StringBuffer str24 = new StringBuffer("Here are 24 characters!!");
StringBuffer str36 = new StringBuffer("Surprise!!! Here are 36 characters!!");
@Test
public void testcharAt(){
Assert.assertEquals('h', str12.charAt(0));
Assert.assertEquals('a', str24.charAt(5));
}
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test
public void testcharAtException(){
thrown.expect(StringIndexOutOfBoundsException.class);
str36.charAt(40);
}
@Test
public void testlength(){
Assert.assertEquals(12, str12.length());
Assert.assertEquals(24, str24.length());
Assert.assertEquals(36, str36.length());
}
@Test
public void testcapacity(){
Assert.assertEquals(28, str12.capacity());
Assert.assertEquals(40, str24.capacity());
Assert.assertEquals(52, str36.capacity());
Assert.assertEquals(82,str24.append("here are 22 characters").capacity());
}
@Test
public void testindex(){
Assert.assertEquals(4, str12.indexOf("a"));
Assert.assertEquals(9, str24.indexOf("24"));
Assert.assertEquals(-1, str36.indexOf("?"));
}
}
查询文档基本都可以得到这些方法的详细信息,只有capacity方法叙述不是很清楚,我一开始理解错了,百度以后才算懂关于Java中StringBuffer的capacity问题,使用不带参数的构造capacity(),默认的大小为length()+16,如果大于16就会对length()*2+2。分析源码应该是最高级最彻底的解决办法了,我一定要学会看源码ヾ(o・ω・)ノ
三、面对对象三要素
- 封装
- 继承
- 多态
先说抽象。抽象我觉得是最根本的概念之一,抽象就是抽出事物的本质特征而暂时不考虑他们的细节。对象、方法、函数都使用了抽象,我们平时其实都在使用抽象而不自知。抽象带来的就是封装,让内部对外透明,只能看见API,要做到这些就要求高内聚低耦合,要不然封装就不完全。随之而来的就是SOLID原则 - SRP(Single Responsibility Principle,单一职责原则)
- OCP(Open-Closed Principle,开放-封闭原则)
- LSP(Liskov Substitusion Principle,Liskov替换原则)
- ISP(Interface Segregation Principle,接口分离原则)
- DIP(Dependency Inversion Principle,依赖倒置原则)
为了不违背以上原则,人们又设计了很多模式,比如这次试验用到的抽象工厂模式
让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确。根据参考链接,我们可以把Double类和Int类看做是两个产品,把Document看做是工厂,因为并没有多种类的产品,所以我认为这里不需要使用抽象工厂模式,工厂模式就可以了。
public class Document {
Data pd;
Document(String choice) {
if (choice.equalsIgnoreCase("Int")){
pd = new Integer();
}
if (choice.equalsIgnoreCase("Double")){
pd = new Double();
}
}
public void displayData(){
pd.displayvalue();
}
}
要扩展的话只需要增加一个Data类的子类,并在Document里增加相应的代码就可以了。
四、练习
任务:以TDD的方式开发一个复数类Complex
先写测试代码,要求全都保留两位小数,toString方法返回a+bi形式
import junit.framework.TestCase;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
public class ComplexTest extends TestCase {
Complex a = new Complex();
Complex b = new Complex(2,-3);
Complex c = new Complex(1.23,3.21);
@Test
public void testequals(){
assertTrue(a.equals(new Complex(0,0)));
assertFalse(b.equals(a));
}
@Test
public void testtoString(){
assertEquals("0.00",a.toString());
assertEquals("2.00-3.00i",b.toString());
assertEquals("1.23+3.21i",c.toString());
}
@Test
public void testComplexAdd(){
assertEquals("2.00-3.00i",a.ComplexAdd(b).toString());
assertTrue(c.ComplexAdd(b).equals(b.ComplexAdd(c)));
}
@Test
public void testComplexSub(){
assertEquals("-0.77+6.21i",c.ComplexSub(b).toString());
assertEquals("-2.00+3.00i",a.ComplexSub(b).toString());
}
@Test
public void testComplexMul(){
assertEquals("0.00",a.ComplexMulti(b).toString());
assertEquals("12.09+2.73i",b.ComplexMulti(c).toString());
}
@Test
public void testComplexDiv(){
try {
assertEquals("0.00", a.ComplexDiv(b).toString());
assertEquals("-0.61-0.86i", b.ComplexDiv(c).toString());
}catch (ComplexDivideZeroException e){
System.exit(1);
}
}
@Test
public void testComplexDivException() {
try{
b.ComplexDiv(a);
fail("Excepted an ComplexDivideZeroException to be thrown.");
}catch (ComplexDivideZeroException e){
assertThat(e.getMessage(),is("除数不能为0"));
}
}
}
然后再根据测试代码实现产品代码并进行调试,最终代码见码云链接
五、问题及解决
问题1:需要测试Complex类发生除0错误时能否正确抛出异常,但是不知道如何使用Junit进行测试
问题1解决方法:JUnit中测试异常抛出的方法有三种解决方法,我只使用了@rule和try...fail...catch两种方法
问题2:Complex类Double类型比较失败
问题2解决方法:百度后知道java中double类型直接用==比较的话永远返回false。另外在重写equals方法的时候,精度的问题也很头疼。后来我想到试试看有没有办法设置精度,这样比较起来就会好办很多,查阅以后知道可以使用format方法,在toString方法中把Complex类的double类型字段格式化成保留小数点后两位,比较的时候也比较toString的返回值。
但是测试的时候值和预期的不太一样,查阅文档才知道format的精度控制是自动四舍五入的。。。这人性化的我都不习惯了。。
六、PSP
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 30分钟 | 15% |
设计 | 30分钟 | 15% |
代码实现 | 50分钟 | 25% |
测试 | 60分钟 | 30% |
分析总结 | 30分钟 | 15% |
2018-2019-2 20175211 实验二《Java面向对象程序设计》实验报告的更多相关文章
- 20145213《Java程序设计》实验二Java面向对象程序设计实验报告
20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...
- 20145206《Java程序设计》实验二Java面向对象程序设计实验报告
20145206<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...
- 20145308刘昊阳 《Java程序设计》实验二 Java面向对象程序设计 实验报告
20145308刘昊阳 <Java程序设计>实验二 Java面向对象程序设计 实验报告 实验名称 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面相对象三要素:封 ...
- 20162311 实验二 Java面向对象程序设计 实验报告
实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...
- 实验二Java面向对象程序设计实验报告(2)
实验二 Java面向对象程序设计 实验概述: 课程:程序设计与数据结构 班级:1623班 姓名: 邢天岳 学号:2309 指导老师:娄老师 王老师 实验日期:2017.4.16 实验名称: Java面 ...
- 实验二 Java面向对象程序设计实验报告
实验二 Java面向对象程序设计 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验 ...
- 20145326《Java程序设计》实验二Java面向对象程序设计实验报告
20145326<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...
- 20155217 实验二 Java面向对象程序设计 实验报告
20155217 实验二 Java面向对象程序设计 实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模 ...
- 20145219 《Java程序设计》实验二 Java面向对象程序设计实验报告
20145219 <Java程序设计>实验二 Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S. ...
- 20162305 实验二 Java面向对象程序设计 实验报告
20162305 实验二 Java面向对象程序设计 实验报告 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D ...
随机推荐
- Sqlserver 锁(转)
转载 http://www.cnblogs.com/zhouqianhua/archive/2011/04/15/2017049.html 总结: 锁的种类: 共享锁\排它锁\更新锁\意向锁\计 ...
- 【原创】C# war3 巨魔精灵 minimap
弃坑LOL后,无聊的时候玩玩 war3的RPG地图,巨魔与精灵. 玩了一段时间精灵....然后玩魔结果总是找不到人.所以就有了这个想法. 代码纯粹靠搬运. 说下原理,网上有份代码,可以查看当前选中目 ...
- Redis数据结构之ziplist
本文及后续文章,Redis版本均是v3.2.8 本篇文章我们来分析下一种特殊编码的双向链表-ziplist(压缩列表),这种数据结构的功能是将一系列数据与其编码信息存储在一块连续的内存区域,这块内存物 ...
- chromedriver与chrome版本映射表
问题: 利用selenium调用谷歌浏览器时报错,后发现是由于浏览器与浏览器驱动不匹配造成的 C:\Users\\Desktop\selenium>python chrome.py[9956:6 ...
- JDK 5~8的特性对比
原文请参考:https://bbs.csdn.net/topics/392062347 jdk5新特性 1.自动装箱和拆箱2.枚举3.静态导入4.可变参数5.內省 是Java语言对Bean类属性. ...
- 美团小程序框架mpvue入门
mpvue 主要特性 使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力: 1. 彻底的组件化开发能力:提高代码复用性 2. 完整的 Vue.js 开发体验 3. 方便的 V ...
- 一天带你入门到放弃vue.js(二)
接下来我们继续学习一天带你入门到放弃系列vue.js(二),如有问题请留言讨论! v-if index.html <div id="app"> <p v-if=& ...
- kvm认识和安装
虚拟化定义: 是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著 ...
- Beta(1/7)
鐵鍋燉腯鱻 项目:小鱼记账 团队成员 项目燃尽图 冲刺情况描述 站立式会议照片 各成员情况 团队成员 学号 姓名 git地址 博客地址 031602240 许郁杨 (组长) https://githu ...
- Python学习——python的常用模块
模块:用一堆代码实现了某个功能的代码集合,模块是不带 .py 扩展的另外一个 Python 文件的文件名. 一.time & datetime模块 import time import dat ...