20175212童皓楨 Java實驗二-面向對象程序設計實驗報告

20175212童皓楨 Java實驗二-面向對象程序設計實驗報告

實驗內容

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

    實驗步驟

    (一)單元測試

  • 在IDEA中建一個項目MyUtil
  • 對於MyUtil類,創建一個MyUtilTest1.java的測試類:
新建一個test文件夾在根目錄中->右鍵選擇Mark Directory as->Test Sources Root

輸入圖片說明
以後在test文件夾中創建一個MyUtilTest1.java的測試類java

  • 在文件中輸入如圖代碼並運行,測試結果以下:

正常狀況
輸入圖片說明編程

邊界狀況
輸入圖片說明設計模式

異常狀況
輸入圖片說明app

(二)TDD(Test Driven Devlopment, 測試驅動開發)

  • 按照教程安裝Juit和JUnitGenerator V2.0
  • 點擊源代碼中的類名MyUtil,選擇Junit3測試用例,創建一個MyUtilTest測試文件編程語言

  • 若TestCase是紅色,則引入junit.jar包
    輸入圖片說明ide

  • 輸入如圖測試代碼並運行,若是測試失敗則出現如圖提示
    輸入圖片說明函數

  • 根提示據修改源代碼,注意邊界異常狀況,修改完善後測試經過
    輸入圖片說明單元測試

(三)以TDD方式研究學習StringBuffer

  • 按照老師給出的程序輸入
public static void main(String [] args){
       StringBuffer buffer = new StringBuffer();
       buffer.append('S');
       buffer.append("tringBuffer");
       System.out.println(buffer.charAt(1));
       System.out.println(buffer.capacity());
       System.out.println(buffer.length());
       System.out.println(buffer.indexOf("tring"));
       System.out.println("buffer = " + buffer.toString());
  • 將方法進行重寫,添加返回值,以便於測試
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);
    }
}
  • 利用API查出並猜想charAt(int i),indexOf(String s),capacity(),length()四種方法的功能。
    輸入圖片說明
    輸入圖片說明
    輸入圖片說明學習

  • 利用JUnit進行測試,並輸入如圖測試代碼,test passed!
    輸入圖片說明

(四)面向對象的三要素

  • 面向對象(Object-Oriented)的三要素包括:封裝、繼承、多態。面向對象的思想涉及到軟件開發的各個方面,如面向對象分析(OOA)、面向對象設計(OOD)、面向對象編程實現(OOP)。OOA根據抽象關鍵的問題域來分解系統,關注是什麼(what)。OOD是一種提供符號設計系統的面向對象的實現過程,用很是接近問題域術語的方法把系統構形成「現實世界」的對象,關注怎麼作(how),經過模型來實現功能規範。OOP則在設計的基礎上用編程語言(如Java)編碼。貫穿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,依賴倒置原則)
      • 高層模塊不該該依賴於低層模塊。兩者都應該依賴於抽象
      • 抽象不該該依賴於細節。細節應該依賴於抽象
  • 模式與設計模式
    • 設計模式有四個基本要素:
      • Pattern name:描述模式,便於交流,存檔
      • Problem:描述何處應用該模式
      • Solution:描述一個設計的組成元素,不針對特例
      • Consequence:應用該模式的結果和權衡(trade-offs)
  • 其餘面對對象原則
    • "組合替代繼承":這是說相對於繼承,要更傾向於使用組合;
    • "笛米特法則":這是說"你的類對其它類知道的越少越好";
    • "共同封閉原則":這是說"相關類應該打包在一塊兒";
    • "穩定抽象原則":這是說"類越穩定,越應該由抽象類組成";

(六)對MyDoc類進行擴充,讓其支持Byte類,初步理解設計模式

題目 :對設計模式示例進行擴充,體會OCP原則和DIP原則的應用,初步理解設計模式,讓系統支持Byte類,並在MyDoc類中添加測試代碼代表添加正確,提交測試代碼和運行結的截圖,加上學號水印

// Server Classes 
abstract class Data {
    abstract public void DisplayValue();
}
class Integer extends  Data {
    int value;
    Integer() {
        value=100;
    }
    public void DisplayValue(){
        System.out.println (value);
    }
}
class Byte extends Data {
    byte value;
    Byte(){
        value=127;
    }
    public void DisplayValue(){
        System.out.println(value);
    }
}
abstract class Factory {
    abstract public Data CreateDataObject();
}
class IntFactory extends Factory {
    public Data CreateDataObject(){
        return new Integer();
    }
}
class ByteFactory extends Factory {
    public Data CreateDataObject(){
        return new Byte();
    }
}
class Document {
    Data pd;
    Document(Factory pf){
        pd = pf.CreateDataObject();
    }
    public void DisplayData(){
        pd.DisplayValue();
    }
}
public class MyDoc {
    static Document d;
    static Document e;
    public static void main(String[] args) {
        e=new Document(new ByteFactory());
        e.DisplayData();
    }
}
  • 運行結果:
    輸入圖片說明

(七)以TDD的方式開發一個複數類Complex

  • 任務:以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)

本道練習題基本考察TDD編碼的節奏。由於本題中實部虛部很容易混淆,致使出錯

輸入圖片說明
所以根據測試代碼來修改產品代碼的優越性得以體現。

  • 產品代碼:
public class Complex{
    private double a;
    private double b;

    public Complex(double a, double b) {
        this.a = a;
        this.b = b;
    }

    public static double getRealPart(double a) {
        return a;
    }

    public static double getImagePart(double b) {
        return b;
    }

    public Complex ComplexAdd(Complex c) {
        return new Complex(a + c.a, b + c.b);
    }
    public Complex ComplexSub(Complex c) {
        return new Complex(a - c.a, b - c.b);
    }
    public Complex ComplexMulti(Complex c) {
        return new Complex(a * c.a - b * c.b, a * c.b + b * c.a);
    }
    public Complex ComplexDiv(Complex c) {
        return new Complex((a * c.b + b * c.a)/(c.b * c.b + c.a * c.a), (b * c.b + a * c.a)/(c.b * c.b + c.a * c.a));
    }

    public String toString() {
        String s = " ";
        if (b > 0)
            s =  a + "+" + b + "i";
        if (b == 0)
            s =  a + "";
        if (b < 0)
            s = a + " " + b + "i";
        return s;
    }
}
  • 測試代碼
import junit.framework.TestCase;
import org.junit.Test;

public class ComplexTest extends TestCase {
    Complex c1 = new Complex(0, 2);
    Complex c2 = new Complex(-1, -1);
    Complex c3 = new Complex(1,1);
    @Test
    public void testgetRealPart() throws Exception {
        assertEquals(-3.0, Complex.getRealPart(-3.0));
        assertEquals(3.0, Complex.getRealPart(3.0));
        assertEquals(0.0, Complex.getRealPart(0.0));
    }
    @Test
    public void testgetImagePart() throws Exception {
        assertEquals(-3.0, Complex.getImagePart(-3.0));
        assertEquals(3.0, Complex.getImagePart(3.0));
        assertEquals(0.0, Complex.getImagePart(0.0));
    }
    @Test
    public void testComplexAdd() throws Exception {
        assertEquals("-1.0+1.0i", c1.ComplexAdd(c2).toString());
        assertEquals("1.0+3.0i", c1.ComplexAdd(c3).toString());
        assertEquals("0.0", c2.ComplexAdd(c3).toString());
    }
    @Test
    public void testComplexSub() throws Exception {
        assertEquals("1.0+3.0i", c1.ComplexSub(c2).toString());
        assertEquals("-1.0+1.0i", c1.ComplexSub(c3).toString());
        assertEquals("-2.0 -2.0i", c2.ComplexSub(c3).toString());
    }
    @Test
    public void testComplexMulti() throws Exception {
        assertEquals("2.0 -2.0i", c1.ComplexMulti(c2).toString());
        assertEquals("-2.0+2.0i", c1.ComplexMulti(c3).toString());
        assertEquals("0.0 -2.0i", c2.ComplexMulti(c3).toString());
    }
    @Test
    public void testComplexComplexDiv() throws Exception {
        assertEquals("-1.0 -1.0i", c1.ComplexDiv(c2).toString());
        assertEquals("1.0+1.0i", c1.ComplexDiv(c3).toString());
        assertEquals("-1.0 -1.0i", c2.ComplexDiv(c3).toString());
    }

}
  • 運行結果截圖
    輸入圖片說明

(八)對實驗二中的代碼進行建模

  • 代碼以下:
public abstract class Animal {
    private String color;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public abstract String shout(); 
}
public class Dog extends Animal{
    public String shout(){
        return "汪汪";
    }
       public String toString(){
        return "The Dog's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
    }
}
public class Cat extends Animal{
    public String shout(){
        return "喵喵";
    }
    public String toString(){
        return "The Cat's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
    }
}
  • 建立的UML類圖

輸入圖片說明

實驗中遇到的問題

  • 問題一:包名Junit提示錯誤
    輸入圖片說明
  • 解決辦法一:參考同窗的博客,摸索出方法,具體以下:
File -> Project Struct... -> Libraies -> 點擊加號 -> Java -> 選擇IDEA目錄下的Lib中的junit-4.12 ->選擇ok

輸入圖片說明

另外的,若是當時安裝是經過Toolbox,IDEA的安裝目錄則頗有可能被隱藏,所以需搜索junit-4.12找到具體路徑後,在管理員權限下解除隱藏才能選擇。
輸入圖片說明

  • 問題二:單元測試時提示找不到main方法。
    輸入圖片說明

  • 解決辦法二: 嘗試修改測試類名與JUnit測試類名不一樣,便可解決。
    輸入圖片說明

感悟和體會

  • 利用API能夠查詢並學習使用一些功能強大的類和方法。
  • 並跟隨TDD方法的節奏設計出僞代碼、產品代碼和測試代碼,有利於本身的程序除了正確性,在更高層面不容易出錯
  • 以後能夠考慮更加改善測試單元的寫法,好比測試例子由計算機窮舉生成。

參考博客

https://www.cnblogs.com/Vivian517/p/6741501.html#YI

相關文章
相關標籤/搜索