標籤:
一、實驗內容
1. 初步掌握單元測試和TDD
2. 理解並掌握物件導向三要素:封裝、繼承、多態
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原則
5. 瞭解設計模式
二、實驗過程(本次實驗都是在自己電腦上完成,沒有使用實驗樓)
(一)單元測試
用程式解決問題時,要會寫三種碼:虛擬碼、產品代碼、測試代碼
這種先寫測試代碼,然後再寫產品代碼的開發方法叫“測試驅動開發”(TDD)
TDD的一般步驟如下:
- 明確當前要完成的功能,記錄成一個測試清單
- 快速完成編寫針對此功能的測試案例
- 測試代碼編譯不通過(沒產品代碼呢)
- 編寫產品代碼
- 測試通過
- 對代碼進行重構,並保證測試通過(重構下次實驗練習)
- 迴圈完成所有功能的開發
(二)物件導向三要素
1.抽象
抽象就是抽出事物的本質特徵而暫時不考慮他們的細節。對於複雜系統問題人們藉助分層次抽象的方法進行問題求解;在抽象的最高層,可以使用問題環境的語言,以概括的方式敘述問題的解。在抽象的較低層,則採用過程化的方式進行描述。在描述問題解時,使用面向問題和面向實現的術語。 程式設計中,抽象包括兩個方面,一是過程抽象,二是資料抽象。
2.封裝、繼承與多態
物件導向(Object-Oriented)的三要素包括:封裝、繼承、多態。
過程抽象的結果是函數,資料抽象的結果是抽象資料類型。
封裝實際上使用方法(method)將類的資料隱藏起來,控制使用者對類的修改和訪問資料的程度,從而帶來模組化(Modularity)和資訊隱藏(Information hiding)的好處;介面(interface)是封裝的準確描述手段。
(三)設計模式初步
(1)S.O.L.I.D原則
物件導向三要素是“封裝、繼承、多態”,任何物件導向程式設計語言都會在文法上支援這三要素。如何藉助抽象思維用好三要素特別是多態還是非常困難的,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,依賴倒置原則)
(2)模式與設計模式
模式是某外在環境(Context) 下﹐對特定問題(Problem)的慣用解決之道。
在物件導向中設計模式的地位可以和面向過程編程中的資料結構的地位相當。
(四)練習
1.使用TDD的方式設計關實現複數類Complex。
虛擬碼:
首先設計一個複數類complex,分別將複數的實部和虛部作為屬性,定義三個構造方法:
①沒有參數時預設為實部和虛部都為0;
②一個參數時預設為實數,即虛部為0,
③兩個參數時分別為實部和虛部
再定義兩個成員方法計算兩個複數的和與差.定義一個print()方法輸出複數的值,當虛部為0時不輸出虛部.
最後定義一個song類使用complex類,在這個類的主方法中建立兩個複數對象,分別計算這兩個複數的和與差並輸出.
產品代碼:
package exp2;
class complex {
double a, b;
complex() {
this.a = 0;
this.b = 0;
}
complex(double a) {
this.a = a;
this.b = 0;
}
complex(double a, double b) {
this.a = a;
this.b = b;
}
complex add(complex p1, complex p2) {
complex p = new complex(p1.a + p2.a, p1.b + p2.b);
return p;
}
complex minus(complex p1, complex p2) {
complex p = new complex(p1.a - p2.a, p1.b - p2.b);
return p;
}
void print() {
System.out.println("複數的值為:");
if (this.b != 0)
System.out.println(this.a + "+" + this.b + "i");
else
System.out.println(this.a);
}
}
測試代碼:
package exp2;
public class song {
public static void main(String[] args) {
complex c = new complex();
complex c1 = new complex(3, 9);
complex c2 = new complex(7, 1);
c1.print();
c2.print();
System.out.println("這兩個複數的和為:");
System.out.println((c.add(c1, c2).a + "+" + c.add(c1, c2).b + "i")
.toString());
System.out.println("這兩個複數的差為:");
System.out
.println((c.minus(c1, c2).a + "+" + c.minus(c1, c2).b + "i")
.toString());
}
}
運行結果:
2.PSP(Personal Software Process)時間
步驟 |
耗時百分比 |
需求分析 |
10% |
設計 |
20% |
代碼實現 |
40% |
測試 |
15% |
分析總結 |
15% |
4.總結單元測試的好處
在單元測試活動中,軟體的獨立單元將在與程式的其他部分相隔離的情況下進行測試,可以尋找錯誤、寫出高品質的代碼、提高編程水平。
經過網上查詢資料,單元測試的好處遠不止我目前發現的這些。它可以使代碼可以放心修改和重構、使程式員從調用者而不是實現者的角度設計軟體模組、
使程式員將軟體模組寫得易於測試和調用,從而有利於解耦、測試本身可作為被測代碼的用法說明,從而替代了一部分文檔功能。
三、遇到的問題及解決方案
1.eclipse提示Animal代碼有錯,Dog和Cat需要在檔案中被定義。解決方案:將Animal和Dog、Cat放在不同的class檔案中編譯
2.設計複數類Complex虛擬碼時不知道應該如何分類。解決方案:網上查詢複數類的構造方法,得知可以定義三類
四、實驗收穫
本次實驗讓我瞭解到想用程式解決實際問題時,不僅是只要寫出一個代碼就可以了,而是最好寫出三種代碼:虛擬碼、產品代碼、測試代碼,這樣的程式才有
實際意義,方便使用。而且運用好單元測試可以在未來的程式設計中讓自己負責的模組功能定義盡量明確,模組內部的改變不會影響其他模組,而且模組的質
量能得到穩定的、量化的保證。希望以後能通過實驗瞭解更多運用java解決實際問題的方法。
java實驗二實驗報告