20145312 實驗二《 Java面向對象程序設計》

20145312 實驗二《 Java面向對象程序設計》

實驗內容

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

(一)單元測試
1.三種代碼
(1)僞代碼:java

百分制轉五分制: 
若是成績小於60,轉成「不及格」 
若是成績在60與70之間,轉成「及格」 
若是成績在70與80之間,轉成「中等」 
若是成績在80與90之間,轉成「良好」 
若是成績在90與100之間,轉成「優秀」 
其餘,轉成「錯誤」

(2)產品代碼與測試代碼
例1:編程

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 "錯誤";
    }
}

該產品代碼的測試代碼(好比輸入爲負分或大於100的成績),代碼以下:設計模式

public class MyUtilTest2 {
    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!");
    }
}

測試結果以下:
數據結構

緣由是判斷不及格時沒有要求成績大於零,修改MyUtil.java,增長對負分的判斷,代碼以下:app

public class MyUtil1 {
    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有測試邊界狀況,對輸入爲「0,60,70,80,90,100」這些邊界狀況進行測試的代碼以下:編程語言

public class MyUtil1Test1 {
    public static void main(String[] args) {
        //測試邊界狀況
        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!");
    }
}

測試結果以下:
模塊化

邊界狀況中輸入100時有錯,修改MyUtil.java,把判斷優秀的條件中包含輸入爲100的狀況,代碼以下:函數

public class MyUtil2 {
    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 "錯誤";
    }
}

這時再利用剛纔的MyUtil1Test1進行測試,獲得測試結果以下:
單元測試

(二)面向對象三要素
1.抽象
(1)抽象就是抽出事物的本質特徵而暫時不考慮他們的細節,對於複雜系統問題人們藉助分層次抽象的方法進行問題求解。
(2)在抽象的最高層,能夠使用問題環境的語言,以歸納的方式敘述問題的解。在抽象的較低層,則採用過程化的方式進行描述。
(3)在描述問題解時,使用面向問題和麪向實現的術語。
(4)程序設計中,抽象包括兩個方面,一是過程抽象,二是數據抽象。過程抽象的結果是函數,數據抽象的結果是抽象數據類型。測試

2.封裝、繼承與多態
(1)面向對象(Object-Oriented)的三要素包括:封裝、繼承、多態。
(2)封裝實際上使用方法(method)將類的數據隱藏起來,控制用戶對類的修改和訪問數據的程度,從而帶來模塊化和信息隱藏的好處。
(3)接口是封裝的準確描述手段。
(三)使用UML建模
建模截圖以下:

(四)設計模式初步1.S.O.L.I.D原則
面向對象三要素是「封裝、繼承、多態」,任何面向對象編程語言都會在語法上支持這三要素。如何藉助抽象思惟用好三要素特別是多態仍是很是困難的,S.O.L.I.D類設計原則是一個很好的指導。
(1)SRP(Single Responsibility Principle,單一職責原則)
(2)OCP(Open-Closed Principle,開放-封閉原則)
(3)LSP(Liskov Substitusion Principle,Liskov替換原則)
(4)ISP(Interface Segregation Principle,接口分離原則)
(5)DIP(Dependency Inversion Principle,依賴倒置原則)

2.模式與設計模式
(1)模式是某外在環境(Context) 下﹐對特定問題(Problem)的慣用解決之道。
(2)在面向對象中設計模式的地位能夠和麪向過程編程中的數據結構的地位至關。

(五)練習
1.使用TDD的方式設計關實現複數類Complex。
(1)僞代碼:

1. Z = a(實部) + bi(虛部);
2.相加:實數部與實部相加,虛部與虛部相加
3.相減:實部與實部相減,虛部與虛部相減
4.相乘
A*B=ac-bd+(ad+bc)i
A=a+bi, B=c+di
5.顯示一個複數
虛部爲負數狀況,不顯示前面的加號

(2)產品代碼

public class Complex{// 1. Z = a(實部) + bi(虛部);

    private int RealPart;   // 實部
    private int ImaginPart; // 虛部

    public int getRealPart() {
        return RealPart;
    }

    public void setRealPart(int r) {
        RealPart = r;
    }

    public int getImaginPart() {
        return ImaginPart;
    }

    public void setImaginPart(int i) {
        ImaginPart = i;
    }
    // 構造函數
    public Complex() {}
    public Complex(int r, int i) {
        super();
        RealPart = r;
        ImaginPart = i;
    }

    // 相加
    public static String add(Complex a,Complex b){
        Complex temp = new Complex();
        temp.setRealPart(a.getRealPart()+b.getRealPart());
        temp.setImaginPart(a.getImaginPart()+b.getImaginPart());
        return show(temp);
    }

    // 相減
    public static String minus(Complex a,Complex b){
        Complex temp = new Complex();
        temp.setRealPart(a.getRealPart()-b.getRealPart());
        temp.setImaginPart(a.getImaginPart()-b.getImaginPart());
        return show(temp);
    }

    //相乘
//A*B=ac-bd+(ad+bc)i
//A=a+bi, B=c+di
    public static String Multi(Complex a,Complex b){
        Complex temp = new Complex();
        temp.setRealPart((a.getRealPart()*b.getRealPart())-(a.getImaginPart()*b.getImaginPart()));
        temp.setImaginPart((b.getImaginPart()*a.getRealPart())+(b.getRealPart()*a.getImaginPart()));
        return show(temp);
    }



    // 顯示輸出
    public static String show(Complex a){
        StringBuffer sb = new StringBuffer();
        sb.append(a.getRealPart());
        if(a.getImaginPart()>0){
            sb.append("+"+a.getImaginPart()+"i");
        }else if(a.getImaginPart()<0){
            sb.append(a.getImaginPart()+"i");
        }
        return sb.toString();
    }
}

(3)測試代碼:

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

import junit.framework.TestCase;
public class ComplexTest1 extends TestCase{
    public void testNoral(){
        assertEquals("4+1i",Complex.minus(new Complex(4,3),new Complex(0,2) ) );
        assertEquals("5+5i",Complex.add(new Complex(4,3),new Complex(1,2) ) );
        assertEquals("2+8i",Complex.Multi(new Complex(1,1),new Complex(5,3) ) );
    }
    public void testNoral1(){
        assertEquals("4+2i",Complex.minus(new Complex(4,3),new Complex(0,1) ) );
        assertEquals("5+5i",Complex.add(new Complex(3,4),new Complex(2,1) ) );
        assertEquals("2+8i",Complex.Multi(new Complex(1,1),new Complex(5,3) ) );
    }
    public void testNoral2(){
        assertEquals("-3-5i",Complex.minus(new Complex(0,0),new Complex(3,5) ) );
        assertEquals("13+12i",Complex.add(new Complex(6,7),new Complex(7,5) ) ) ;
        assertEquals("0",Complex.Multi(new Complex(0,0),new Complex(3,5) ) );
    }
}

測試結果以下:

4)建模截圖以下:

相關文章
相關標籤/搜索