1. 程式人生 > >2017-2018-2 20165231實驗二《Java面向對象程序設計》實驗報告

2017-2018-2 20165231實驗二《Java面向對象程序設計》實驗報告

步驟 code 對話 append strac 三種 意圖 加水印 原則

實驗報告封面

  • 課程:Java程序設計 班級:1652班 姓名:王楊鴻永 學號:20165231

  • 指導教師:婁嘉鵬 實驗日期:2018年4月16日

  • 實驗時間:13:45 - 15:25 實驗序號:實驗二

  • 實驗名稱:Java面向對象程序設計

實驗內容:

  1. 初步掌握單元測試和TDD
  2. 理解並掌握面向對象三要素:封裝、繼承、多態
  3. 初步掌握UML建模
  4. 熟悉S.O.L.I.D原則
  5. 了解設計模式

實驗知識點:
1、TDD的一般步驟如下:

  • 明確當前要完成的功能,記錄成一個測試列表
  • 快速完成編寫針對此功能的測試用例
  • 測試代碼編譯不通過(沒產品代碼呢)
  • 編寫產品代碼
  • 測試通過
  • 對代碼進行重構,並保證測試通過(重構下次實驗練習)
  • 循環完成所有功能的開發

2、面向對象(Object-Oriented)的三要素包括:封裝、繼承、多態。

3、封裝就是將數據與相關行為包裝在一起以實現信息就隱藏。Java中用類進行封裝。

4、繼承指一個類的定義可以基於另外一個已經存在的類,即子類基於父類,從而實現父類代碼的重用。繼承是實現軟件可重用的根基,是提高軟件系統的可擴展性與可維護性的主要途徑。

5、面向對象三要素是“封裝、繼承、多態”,任何面向對象編程語言都會在語法上支持這三要素。如何借助抽象思維用好三要素特別是多態還是非常困難的,S.O.L.I.D類設計原則是一個很好的指導:

  • SRP(Single Responsibility
  • Principle,單一職責原則)
  • OCP(Open-Closed Principle,開放-封閉原則)
  • LSP(Liskov SubstitusionPrinciple,Liskov替換原則)
  • ISP(Interface Segregation Principle,接口分離原則)
  • DIP(Dependency Inversion Principle,依賴倒置原則)

實驗步驟

第一個提交點

參考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 完成單元測試的學習  
提交最後三個JUnit測試用例(正常情況,錯誤情況,邊界情況)都通過的截圖,截圖上要有畫圖加水印,輸入自己的學號  
本提交點考查JUnit會不會使用,測試用例至少要包含正常情況,錯誤情況,邊界情況的測試  

三種代碼

編程是智力活動,不是打字,編程前要把幹什麽、如何幹想清楚才能把程序寫對、寫好。與目前不少同學一說編程就打開編輯器寫代碼不同,我希望同學們養成一個習慣,當你們想用程序解決問題時,要會寫三種碼:

  • 偽代碼
  • 產品代碼
  • 測試代碼

偽代碼:偽代碼從意圖層面來解決問題,是產品代碼最自然的、最好的註釋

百分制轉五分制:
如果成績小於60,轉成“不及格”
如果成績在60與70之間,轉成“及格”
如果成績在70與80之間,轉成“中等”
如果成績在80與90之間,轉成“良好”
如果成績在90與100之間,轉成“優秀”
其他,轉成“錯誤”

  • 產品代碼:按照偽代碼的思路逐步實現程序的就是產品代碼
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 "錯誤";
   }
}
  • 測試代碼:為了防止Bug沒發現而將產品提交給別人,可以使用測試代碼測試bug。
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));
    }
    @Test
    public void testExceptions(){
        assertEquals("錯誤",MyUtil.percentage2fivegrade(105));
        assertEquals("錯誤",MyUtil.percentage2fivegrade(-55));
    }

    @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));
    }
}

我們是該“先寫產品代碼,然後再寫測試代碼,通過測試發現了一些Bugs,修改代碼”,還是該“先寫測試代碼,然後再寫產品代碼,從而寫出來的代碼就是正確的”呢?當然先寫測試代碼了。這種先寫`測試代碼,然後再寫產品代碼的開發方法叫“測試驅動開發”(TDD)。TDD的一般步驟如下:

  • 明確當前要完成的功能,記錄成一個測試列表
  • 快速完成編寫針對此功能的測試用例
  • 測試代碼編譯不通過(沒產品代碼呢)
  • 編寫產品代碼
  • 測試通過
  • 對代碼進行重構,並保證測試通過(重構下次實驗練習)
  • 循環完成所有功能的開發

Java中有單元測試工具JUnit來輔助進行TDD,IDEA中使用JUnit要安裝插件,選擇File->Setting打開設置對話框:
技術分享圖片
在設置對話框中選擇Plugins, 單擊Install JetBrains plugin...按鈕打開插件安裝界面:
技術分享圖片
在插件安裝對話框的搜索中輸入junit,單擊JunitGenerator V2.0,單擊右邊綠色的Install按鈕安裝:
技術分享圖片
安裝完成:
技術分享圖片

然後在IDEA中新建一個空的類,鼠標單擊類名會出現一個燈泡狀圖標,單擊圖標或按Alt + Entert,在彈出的菜單中選擇Create Test後自動生成一個test類
技術分享圖片
技術分享圖片
技術分享圖片

如果TestCase是紅色的,需要在IDEA中的項目(模塊)中加入junit.jar包,junit.jar包的位置一般在安裝目錄下lib文件夾中可以找到,然後在IDEA中選擇菜單File->Project Structure...在彈出的對話框中選擇Dependancies標簽頁,單擊+號,選擇JARs or Directories...,輸入junit的文件地址。

最後run測試類,所有test通過就算是通過了.(新版本的IDEA可能沒有老版本的小綠條和小紅條,但是會有小綠勾和橙感嘆)
技術分享圖片
技術分享圖片

測試結果:
技術分享圖片

第二個提交點

  • 參考 積極主動敲代碼,使用JUnit學習Java (http://www.cnblogs.com/rocedu/p/4837092.html)
  • 以 TDD的方式研究學習StringBuffer
  • 提交你的單元測試用例和測試通過的截圖,截圖要加上學號水印
  • 測試自己會不會寫JUnit測試用例

根據老師給的代碼,進行對Junit的應用。

public class StringBufferDemo{        
  public static void main(String [] args){    
     StringBuffer buffer = new StringBuffer(20);    
     buffer.append(‘S‘);     
     buffer.append("tringBuffer");     
     System.out.println(buffer.charAt(1));     
     System.out.println(buffer.capacity();     
     System.out.println(buffer.indexOf("tring12345"));    
     System.out.println("buffer = " + buffer.toString());
     System.out.println(buffer.length());
 }    
}

產品代碼:

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);
    }
}

測試代碼:

import junit.framework.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;

public class StringBufferDemoTest extends TestCase {
    StringBuffer a = new StringBuffer("StringBuffer");
    StringBuffer b = new StringBuffer("StringBufferStringBuffer");
    StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer");

    @Test
    public void testcharAt() throws Exception {
        assertEquals(‘S‘,a.charAt(0));
        assertEquals(‘B‘,a.charAt(6));
        assertEquals(‘r‘,a.charAt(11));
    }

    @Test
    public void testcapacity() throws Exception {
        assertEquals(28, a.capacity());
        assertEquals(40, b. capacity());
        assertEquals(52, c.capacity());
    }

    @Test
    public void testlength() throws Exception {
        assertEquals(12, a.length());
        assertEquals(24, b.length());
        assertEquals(36, c.length());
    }

    @Test
    public void testindexOf() throws Exception {
        assertEquals(0, a.indexOf("Str"));
        assertEquals(6, a.indexOf("Buf"));
        assertEquals(10,a.indexOf("er"));
    }
}

按照提交點一的步驟測試
測試截圖:
技術分享圖片

第三個提交點

參考實驗二 Java面向對象程序設計
對設計模式示例進行擴充,體會OCP原則和DIP原則的應用,初步理解設計模式
用自己的學號%6進行取余運算,根據結果進行代碼擴充 :
0:讓系統支持Byte類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印
1:讓系統支持Short類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印
2:讓系統支持Boolean類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印
3:讓系統支持Long類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印
4:讓系統支持Float類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印
5:讓系統支持Double類,並在MyDoc類中添加測試代碼表明添加正確,提交測試代碼和運行結的截圖,加上學號水印

代碼如下:測試支持short型

abstract class Data {
        abstract public void DisplayValue();
    }
    class Integer extends  Data {
        int value;
        Integer() {
            value=31;
        }
        public void DisplayValue(){
            System.out.println (value);
        }
    }
    // Pattern Classes
    abstract class Factory {
        abstract public Data CreateDataObject();
    }
    class IntFactory extends Factory {
        public Data CreateDataObject(){
            return new Integer();
        }
    }
    //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;
        public static void main(String[] args) {
            d = new Document(new IntFactory());
            d.DisplayData();
        }
    }

測試截圖:
技術分享圖片

第四個提交點

提交:單元測試代碼和運行成功截圖及碼雲上代碼鏈接,截圖要加上學號水印

參考http://www.cnblogs.com/rocedu/p/6736847.html

任務:以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 {
    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 c) {
        return new Complex(r + c.r, i + c.i);
    }

    public Complex ComplexSub(Complex c) {
        return new Complex(r - c.r, i - c.i);
    }

    public Complex ComplexMulti(Complex c) {
        return new Complex(r * c.r - i * c.i, r * c.i + i * c.r);
    }

    public Complex ComplexDiv(Complex c) {
        return new Complex((r * c.i + i * c.r) / (c.i * c.i + c.r * c.r), (i * c.i + r * c.r) / (c.i * c.i + c.r * c.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;
    }
}

測試代碼:

import junit.framework.TestCase;
import  org.junit.Test;

public class ComplexTest extends TestCase {
  Complex a =new Complex(0,3);
  Complex b=new Complex(-1,-1);

  @Test
    public void testComplexAdd() throws Exception {
      assertEquals("-1.0+2.0i",a.ComplexAdd(b).toString());
  }

  @Test
  public void testComplexSub() throws Exception {
      assertEquals("1.0+4.0i", a.ComplexSub(b).toString());
  }

    @Test
    public void testComplexMulti() throws Exception {
        assertEquals("3.0 -3.0i", a.ComplexMulti(b).toString());
    }

    @Test
    public void testComlexDiv() throws Exception {
        assertEquals("-1.5 -1.5i", a.ComplexDiv(b).toString());
    }
}

測試結果:
技術分享圖片

實驗總結和體會

本次實驗開始覺得很有難道,從沒有接觸過什麽TDD,什麽測試代碼之類的,看了一下午的博客終於看出點名堂了,然後開始參考著手設計。偽代碼 產品代碼 測試代碼對以後的編程設計由著極大的幫助,偽代碼相當於立意提綱,測試代碼檢查bug,就可以設計出比較完美的程序了。

2017-2018-2 20165231實驗二《Java面向對象程序設計》實驗報告