20155236 《Java程序设计》实验一(Java开发环境的熟悉)实验报告

一、实验内容及步骤

实验内容

1.初步掌握单元测试和TDD
2.理解并掌握面向对象三要素:封装、继承、多态
3.初步掌握UML建模
4.熟悉S.O.L.I.D原则
5.了解设计模式

实验步骤

(一)单元测试
以MyUtil为列,进行代码编写

需求:我们要在一个MyUtil类中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。

  • 伪代码:
    百分制转五分制:
    如果成绩小于60,转成“不及格”
    如果成绩在60与70之间,转成“及格”
    如果成绩在70与80之间,转成“中等”
    如果成绩在80与90之间,转成“良好”
    如果成绩在90与100之间,转成“优秀”
    其他,转成“错误”
  • 产品代码:
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 "错误";
   }
  }

先根据伪代码写出原始代码,接下来我们可以用测试代码检验我们的产品代码是否完善。

  • 测试代码:
public class MyUtilTest {  
  public static void main(String[] args) {  
      //测试出错情况  
      if(MyUtil.percentage2fivegrade(-10) != "错误")  
          System.out.println("test failed 1!");  
      else if(MyUtil.percentage2fivegrade(115) != "错误")  
          System.out.println("test failed 2!");
      else   
          System.out.println("test passed!");     
      //测试边界情况   
      if(MyUtil.percentage2fivegrade(0) != "不及格")   
          System.out.println("test failed 1!");  
      else if(MyUtil.percentage2fivegrade(60) != "及格")   
          System.out.println("test failed 2!");  
      else if(MyUtil.percentage2fivegrade(70) != "中等")  
          System.out.println("test failed 3!");  
      else if(MyUtil.percentage2fivegrade(80) != "良好")  
          System.out.println("test failed 4!");  
      else if(MyUtil.percentage2fivegrade(90) != "优秀")  
          System.out.println("test failed 5!");  
      else if(MyUtil.percentage2fivegrade(100) != "优秀")  
          System.out.println("test failed 6!");  
      else   
          System.out.println("test passed!");   
   }  
  }
  • 经过一系列测试后,我们将产品代码完善为:
public class MyUtil{
 public static String percentage2fivegrade(int grade){
     //如果成绩小于0,转成“错误”
     if ((grade < 0))
         return "错误";
     //如果成绩小于60,转成“不及格”
     else 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 "优秀";
     //如果成绩大于100,转成“错误”
     else
         return "错误";
  }
 }

我们是完成了对MyUtil边界,以及超额情况的修正,保证了我们代码的安全性,现在它才是一个完整的++产品代码++。

(2) TDD(Test Driven Devlopment, 测试驱动开发)

明确当前要完成的功能,记录成一个测试列表
快速完成编写针对此功能的测试用例
测试代码编译不通过(没产品代码呢)
编写产品代码
测试通过
对代码进行重构,并保证测试通过(重构下次实验练习)
循环完成所有功能的开发

首先我们要了解TDD的编码节奏是:

  • 增加测试代码,JUnit出现红条
  • 修改产品代码
  • Junit出现绿条,任务完成

先跟着老师给的TDD实例走了一遍,然后对于StringBufferDemo进行了TDD编码,截图如下:

java程序 test_测试

(3)学号%6后进行题目的挑选,我的是0:使系统接受Byte类。

根据老师给的范例,添加代码使得Byte类被接受。

为了防止“拷贝黏贴”式开发,我们必须学会过程抽象,

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,依赖倒置原则)

代码及运行截图:

java程序 test_System_02

(4)使用TDD的方式设计关实现复数类Complex

/**
• Created by apple on 2017/4/21.
*/
 public class Complex {
private double realPart;
private double imaginPart;
public Complex(){
    double realPart;
    double imaginPart;
}
public Complex(double r,double i){
    double realPart;
    double imaginPart;
    this.realPart=r;
    this.imaginPart=i;
}
public double getRealPart(){
    return realPart;
}
public double getImaginPart(){
    return imaginPart;
}
public void setRealPart(double d){
    this.realPart=d;
}

public void setImaginPart(double d) {
    this.imaginPart =d;
}
public void ComplexAdd(Complex c){
    this.realPart+=c.realPart;
    this.imaginPart+=c.imaginPart;
}
public void ComplexAdd(double c){
    this.realPart+=c;
}
public void ComplexMinus(Complex c){
    this.realPart-=c.realPart;
    this.imaginPart-=c.imaginPart;
}
public void ComplexMinus(double c){
    this.realPart-=c;
}
public void ComplexMulti(Complex c){
    this.realPart*=c.realPart;
    this.imaginPart*=c.imaginPart;
}
public void ComplexMulti(double c){
    this.realPart*=c;
}


(5)画图
1.抽象
"去粗取精、化繁为简、由表及里、异中求同"。抽象就是抽出事物的本质特征而暂时不考虑他们的细节。对于复杂系统问题人们借助分层次抽象的方法进行问题求解;在抽象的最高层,可以使用问题环境的语言,以概括的方式叙述问题的解。在抽象的较低层,则采用过程化的方式进行描述。在描述问题解时,使用面向问题和面向实现的术语。程序设计中,抽象包括两个方面,一是过程抽象,二是数据抽象。

2.封装、继承与多态
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。过程抽象的结果是函数,数据抽象的结果是抽象数据类型(Abstract Data Type,ADT),类可以作具有继承和多态机制的ADT。数据抽象才是OOP的核心和起源。

OO三要素的第一个要素是封装,封装就是将数据与相关行为包装在一起以实现信息就隐藏。Java中用类进行封装。
封装实际上使用方法(method)将类的数据隐藏起来,控制用户对类的修改和访问数据的程度,从而带来模块化(Modularity)和信息隐藏(Information hiding)的好处;接口(interface)是封装的准确描述手段。

java程序 test_java程序 test_03

步骤

耗时

百分比

需求分析

30 min

15.38%

设计

1 h

30.77%

代码实现

1 h

30.77%

测试

30min

15.38%

分析总结

15min

7.69%