20165227 实验二《Java面向对象程序设计》实验报告
2017-2018-4 20165227实验二《Java面向对象程序设计》实验报告
实验内容
- 初步掌握单元测试和TDD
- 理解并掌握面向对象三要素:封装、继承、多态
- 初步掌握UML建模
- 熟悉S.O.L.I.D原则
- 了解设计模式
实验要求
- 没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程
- 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
- 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
实验步骤
一、单元测试
1、三种代码
要了解并养成用写三种代码来编程的习惯
- 伪代码
- 产品代码
- 测试代码
举个例子:我们要在一个MyUtil类
中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。
先写伪代码
,伪代码与具体编程语言无关,不要写与具体编程语言语法相关的语句,伪代码
从意图层面来解决问题,最终,伪代码
是产品代码
最自然的、最好的注释。
百分制转五分制:
如果成绩小于60,转成“不及格”
如果成绩在60与70之间,转成“及格”
如果成绩在70与80之间,转成“中等”
如果成绩在80与90之间,转成“良好”
如果成绩在90与100之间,转成“优秀”
其他,转成“错误”
写完伪代码
后,就可以用特定的编程语言翻译一下,就是可用的产品代码
了。这里使用JavaMyUtil.java
:
public class MyUtil{
public static String percentage2fivegrade(int grade){
//如果成绩小于60,转成“不及格”
if (grade < 60)
return "不及格";
//如果成绩在60与70之间,转成“及格”
else if (grade < 70)
return "及格";
//如果成绩在70与80之间,转成“中等”
else if (grade < 80)
return "中等";
//如果成绩在80与90之间,转成“良好”
else if (grade < 90)
return "良好";
//如果成绩在90与100之间,转成“优秀”
else if (grade < 100)
return "优秀";
//其他,转成“错误”
else
return "错误";
}
}
一般来说产品代码
出来后,大部分工作可以说是完成了,但是,谁能保证你的产品代码不会出现bug或者错误呢?所以这个时候就需要编写测试代码
,通过测试代码
能够更好的完善最后的产品代码
~
在IDEA中我们可以借助单元测试工具JUnit来辅助进行TDD,直接点击Create Test
就可以了
而且,测试代码仅测试一种情况往往是不够的,通常来说会进行三个方面的测试:
正常情况
import org.junit.Test;
import junit.framework.TestCase;
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));
}
}
异常情况
import org.junit.Test;
import junit.framework.TestCase;
public class MyUtilTest extends TestCase {
@Test
public void testException() {
assertEquals("错误", MyUtil.percentage2fivegrade(-55));
assertEquals("错误", MyUtil.percentage2fivegrade(105));
}
}
边界情况
import org.junit.Test;
import junit.framework.TestCase;
public class MyUtilTest extends TestCase {
@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));
}
}
如果测试通过就会显示
test passed
如果测试没通过,则会显示红色,并显示
test failed
,而且会告知哪里出了错误
通过最后的测试代码
的成功测试后,我们的产品代码
才算是真正的完工了。当然,测试代码
的编写不能随意,应该尽可能地考虑周全,才能很好的完善产品代码
码云链接:
MyUtil.java
MyUtilTest.java
二、TDD(Test Driven Devlopment, 测试驱动开发)
- 先写
测试代码
,再写产品代码
的TDD的一般步骤如下:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过(没产品代码呢)
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过(重构下次实验练习)
- 循环完成所有功能的开发
- TDD的编码节奏是:
- 增加测试代码,JUnit出现红条
- 修改产品代码
- JUnit出现绿条,任务完成
- 老师给的
StringBuffer
的例子 积极主动敲代码,使用JUnit学习Java
public class StringBufferDemo{
public static void main(String [] args){
StringBuffer buffer = new StringBuffer();
buffer.append('S');
buffer.append("tringBuffer");
System.out.println(buffer.length());
System.out.println(buffer.charAt(1));
System.out.println(buffer.capacity();
System.out.println(buffer.indexOf("tring"));
System.out.println("buffer = " + buffer.toString());
}
}
首先我们需要改写一下例子中的程序,使其能够使用TDD来测试。改代码之前我们得知道StringBufferDemo类中的方法都是什么功能,才能知道我们需要测试哪些内容。通过查阅资料,得知
StringBuffer( )
:分配16个字符的缓冲区length()
:返回字符串的长度charAt(int i)
:返回此序列中指定索引处的 char 值。第一个 char 值在索引 0 处,第二个在索引 1 处,依此类推capacity()
:返回string分配的存储容量indexOf(String s)
:返回输入的子字符串的第一个字母在母字符串的位置
最后的出的产品代码:
public class StringBufferDemo{
StringBuffer buffer = new StringBuffer();
public StringBufferDemo(StringBuffer buffer){
this.buffer = buffer;
}
public Character charAt(int i){
return buffer.charAt(i);
}
public int capacity(){
return buffer.capacity();
}
public int length(){
return buffer.length();
}
public int indexOf(String buf) {
return buffer.indexOf(buf);
}
}
通过IDEA中的TDD写出的测试代码:
import junit.framework.TestCase;
import org.junit.Test;
public class StringBufferDemoTest extends TestCase {
StringBuffer a = new StringBuffer("zhuyueniupi");//(<=16)
StringBuffer b = new StringBuffer("zhuyueniupizhuyueniupi");//(>16&&<=34)
StringBuffer c = new StringBuffer("zhuyueniupizhuyueniupizhuyueniupi");//(>=34)
@Test
public void testcharAt() throws Exception{
assertEquals('z',a.charAt(0));
assertEquals('u',a.charAt(2));
assertEquals('p',a.charAt(9));
assertEquals('i',a.charAt(10));
}
@Test
public void testcapacity() throws Exception{
assertEquals(27,a.capacity());
assertEquals(38,b.capacity());
assertEquals(49,c.capacity());
}
@Test
public void testlength() throws Exception{
assertEquals(11,a.length());
assertEquals(22,b.length());
assertEquals(33,c.length());
}
@Test
public void testindexOf() throws Exception{
assertEquals(0,a.indexOf("zh"));
assertEquals(3,a.indexOf("yueniu"));
assertEquals(7,a.indexOf("iupi"));
}
}
测试运行截图:
码云链接:
StringBufferDemo.java
StringBufferDemoTest.java
三、面向对象三要素
- 抽象
程序设计中,抽象包括两个方面,一是过程抽象,二是数据抽象
例如:打印“1-100”这种大数据的时候
public void printn(int n){
for(int i=1; i<=n; i++)
System.out.println(n);
}
而且能够更地简便打印
printn(3);
封装、继承与多态
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。
包括:面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程实现(OOP)- 设计模式初步
S.O.L.I.D原则: - SRP(Single Responsibility Principle,单一职责原则)
- OCP(Open-Closed Principle,开放-封闭原则)
- LSP(Liskov Substitusion Principle,Liskov替换原则)
- ISP(Interface Segregation Principle,接口分离原则)
DIP(Dependency Inversion Principle,依赖倒置原则)
码云链接:
MyDoc.java
四、练习
- 要求:使用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)产品代码:
public class Complex {
// 定义属性并生成getter,setter
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;
}
//Override Object
public boolean equals(Object obj){
Complex complex=(Complex) obj;
if (complex.r!=r) {
return false;
}
if(complex.i!=i){
return false;
}
return true;
}
public String toString(){
String str=new String();
if (i==0) str=r+"";
else if(i<0) str=r + ""+i+"i";
else str=r+""+"+"+i+"i";
return str;
}
// 定义公有方法:加减乘除
Complex ComplexAdd(Complex a){
return new Complex(r+a.r,i+a.i);
}
Complex ComplexSub(Complex a){
return new Complex(r-a.r,i-a.i);
}
Complex ComplexMulti(Complex a){
return new Complex(ra.r-ia.i,ra.i+ia.r);
}
Complex ComplexDiv(Complex a){
return new Complex((ra.r+ia.i)/(a.ra.r+a.ia.i),(ia.r-ra.i)/(a.ra.r+a.ia.i));
}
}测试代码:
import junit.framework.TestCase;
import org.junit.Test;
public class ComplexTest extends TestCase {
Complex a=new Complex(1,2);
Complex b=new Complex(-2,-1);
Complex c=new Complex(4,-2);
Complex d=new Complex(4,-2);
@Test
public void testequals(){
assertEquals(false,a.equals(b));
assertEquals(false,b.equals(c));
assertEquals(true,c.equals(d));
}
@Test
public void testAdd(){
assertEquals(new Complex(-1,1),a.ComplexAdd(b));
assertEquals(new Complex(5,0),a.ComplexAdd(c));
}
@Test
public void testSub(){
assertEquals(new Complex(3,3),a.ComplexSub(b));
assertEquals(new Complex(-3,4),a.ComplexSub(c));
}
@Test
public void testMulti(){
assertEquals(new Complex(0,-5),a.ComplexMulti(b));
assertEquals(new Complex(8,6),a.ComplexMulti(c));
}
@Test
public void testDiv(){
assertEquals(new Complex(0,0.5),a.ComplexDiv(c));
assertEquals(new Complex(-0.3,-0.4),b.ComplexDiv(c));
}
}
码云链接:
Complex.java
ComplexTest.java
五、实验感想
这次的实验比之前的难度都有所提升,主要是学习了有关IDEA中单元测试工具JUnit来辅助进行TDD的主要知识点,让我们了解并学习了三种代码:伪代码
,产品代码
,测试代码
。让我们的编写程序的理念进行了提升,同时也学到了新的代码编写和测试的方法,很有意义。
实验中遇到的问题
- 在使用Junit的时候,
import junit.framework.TestCase;
中的Junit
显示红色
提示是程序包org.junti不存在
,后来通过百度查找解决了这个问题
@Test
是红色的
在老师的博客中有解决方法
直接File
中点击Project Structure
,然后找到Modules
里的Dependencies
添加junit.jar
其中对于junit.jar
的地址查询可以用Everything软件快捷查到
PSP(Personal Software Process)时间
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 40min | 20% |
设计 | 60min | 30% |
代码实现 | 70min | 30% |
测试 | 20min | 10% |
分析总结 | 20min | 10% |
20165227 实验二《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 理解并掌握面相对象三要素:封 ...
- 实验二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 ...
- 20145239杜文超 《Java程序设计》实验二 Java面向对象程序设计实验报告
20145239 <Java程序设计>实验二 Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S. ...
随机推荐
- 根据端口号,利用DOS命令杀死进程
比如利用DOS命令找出占用8080端口的程序的PID 然后用DOS命令杀死该进程 kill
- HDU3452_Bonsai
题目的意思是给你一个棵树,每天边上有一个权值,现在要想根节点和每个叶子节点完全隔离开来,删除一些边,求最少需要删除的边权值综合是多少? 直接建模,以根节点为汇点,每个叶子节点连接虚拟源点流量无穷,树上 ...
- 概率主题模型简介 Introduction to Probabilistic Topic Models
此文为David M. Blei所写的<Introduction to Probabilistic Topic Models>的译文,供大家参考. 摘要:概率主题模型是一系列旨在发现隐藏在 ...
- BZOJ2878 NOI2012迷失游乐园(树形dp+环套树+概率期望)
考虑树的部分分怎么做.令f[i]为i向子树内走的期望路径长度,转移比较显然.算答案时先把其父亲的答案弄好就可以统计自己的答案了. 环套树也类似.树里直接dp,对环上点暴力考虑环上的每条路径,算完后再在 ...
- 关于字符编码:ascii、unicode与utf-8
转自:https://foofish.net/unicode_utf-8.html 阮一峰老师对普及计算机基础技术功不可没,但毕竟老师不是神,因此也避免不了对某些概念有一些错误的理解,<字符编码 ...
- Unity使用C#实现简单Scoket连接及服务端与客户端通讯
简介: 网络编程是个很有意思的事情,偶然翻出来很久之前刚开始看Socket的时候写的一个实例,贴出来吧 Unity中实现简单的Socket连接,c#中提供了丰富的API,直接上代码. 服务端代码: [ ...
- PHP是什么?
PHP是什么? PHP是一门后端动态解释型计算机高级语言,一般用来编写或者生成动态网页,主要负责数据的处理与渲染.(这里是指用PHP嵌入网页里面的形式,现在可以直接用一些JS的框架去渲染网页数据了,P ...
- phpredis用法笔记
项目中用到redis集群, 发现phpredis对集群,分布式是有支持的.翻译下相关资料备用. redis扩展地址:https://github.com/phpredis/phpredis, 看到如下 ...
- java线程池赏析
1.线程池的顶级接口(Executor) 线程池的顶级接口(jdk > 1.5).仅仅定义了方法execute(Runnable). 该方法接收一个Runnable实例,用来执行一个任务,该任务 ...
- 谷歌发布 Android 8.1 首个开发者预览版,优化内存效率
今晨,谷歌推出了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化,其中包含对 Android Go (设备运行内存小于等于 1 GB)和加速设备上对机器学习的全新神经网 ...