標籤:
北京電子科技學院(BESTI)
實 驗 報 告
課程:Java 班級: 1352 姓名:姬夢馨 學號:20135218
成績: 指導教師:婁嘉鵬 實驗日期:2015.5.8
實驗密級: 預習程度: 實驗時間:15:30~18:00
儀器組次:18 必修/選修:選修 實驗序號:02
實驗名稱: Java物件導向程式設計
實驗目的與要求:
1. 初步掌握單元測試和TDD
2. 理解並掌握物件導向三要素:封裝、繼承、多態
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原則
5. 瞭解設計模式
實驗儀器:
統計的PSP(Personal Software Process)時間
步驟 |
耗時(min) |
百分比 |
需求分析 |
15 |
7.5% |
設計 |
40 |
20% |
代碼實現 |
45 |
22.50% |
測試 |
40 |
20% |
分析總結 |
60 |
30% |
實驗內容一:
(一)單元測試
(1) 三種代碼
編程前要把幹什麼、如何幹想清楚才能把程式寫對、寫好。想用程式解決問題時,要會寫三種碼:
現在,我們通過一個例子說明如何寫這三種代碼。
需求:我們要在一個MyUtil類中解決一個百分製成績轉成“優、良、中、及格、不及格”五級製成績的功能。
虛擬碼:
如果成績小於60,不及格
如果成績在60~70,及格
如果成績在70~80,中等
如果成績在80~90,良好
如果成績在90~100,優秀
產品代碼:
用java將虛擬碼翻譯一下
測試代碼:
用於測試產品代碼。
嘗試了50這個數字
但是50是顯然不夠的,下邊多測試幾組資料。
再測試一下-10和115這種錯誤資料,發現運行-10的結果不對,進行修改,測試通過。
測試一下邊界資料:
發現100不對,進行修改代碼,測試通過。
(2)TDD(Test Driven Devlopment, 測試驅動開發)
先寫測試代碼,然後再寫產品代碼的開發方法叫“測試驅動開發”(TDD)。
TDD的一般步驟如下:
- 明確當前要完成的功能,記錄成一個測試清單
- 快速完成編寫針對此功能的測試案例
- 測試代碼編譯不通過(沒產品代碼呢)
- 編寫產品代碼
- 測試通過
- 對代碼進行重構,並保證測試通過(重構下次實驗練習)
- 迴圈完成所有功能的開發
基於TDD,我們不會出現過度設計的情況,需求通過測試案例表達出來了,我們的產品代碼只要讓測試通過就可以了。
依然以上述例子為例:
我們增加第一個測試案例,測試案例方法名任意,輸入以下代碼:
此時代碼存在語法錯誤,原因很簡單,MyUtil類還不存在,類中的percentage2fivegrade方法也不存在,我們在TDDDemo的src目錄中建立一個MyUnil的類,並實現percentage2fivegrade方法,如所示:
點擊右鍵,進行運行調試
測試結果出現了一個紅條(red bar),說明測試沒通過,輸入以下代碼,進行調試成功。
增加一個測試異常情況,運行調試成功。
(二)物件導向三要素
(1)抽象
抽象就是抽出事物的本質特徵而暫時不考慮他們的細節。對於複雜系統問題人們藉助分層次抽象的方法進行問題求解;在抽象的最高層,可以使用問題環境的語言,以概括的方式敘述問題的解。在抽象的較低層,則採用過程化的方式進行描述。在描述問題解時,使用面向問題和面向實現的術語。 程式設計中,抽象包括兩個方面,一是過程抽象,二是資料抽象。
(2)封裝、繼承與多態(三要素)
封裝實際上使用方法(method)將類的資料隱藏起來,控制使用者對類的修改和訪問資料的程度,從而帶來模組化(Modularity)和資訊隱藏(Information hiding)的好處;介面(interface)是封裝的準確描述手段。
以封裝為基礎,繼承可以實現代碼複用,需要注意的是,繼承更重要的作用是實現多態。
多態是指不同的類對象調用同一個簽名的成員方法時將執行不同代碼的現象。多態是物件導向程式設計的靈活性和可擴充性的基礎。
(三)設計模式初步
物件導向三要素是“封裝、繼承、多態”,任何物件導向程式設計語言都會在文法上支援這三要素。如何藉助抽象思維用好三要素特別是多態還是非常困難的,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,依賴倒置原則)
OCP是OOD中最重要的一個原則,OCP的內容是
- software entities (class, modules, function, etc.) should open for extension,but closed for modification.
-
- 軟體實體(類,模組,函數等)應該對擴充開放,對修改封閉。
- SRP的內容是:
- There should never be more than one reason for a class to change
- 決不要有一個以上的理由修改一個類
- LSP的內容是:
- Subtypes must be substitutable for their base types
- Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
- 子類必須可以被其基類所代
- 使用指向基類的指標或引用的函數,必須能夠在不知道具體衍生類別物件類型的情況下使用它
DIP的內容是:
- High level modules should not depend upon low level modules. Both should depend upon abstractions
- Abstractions should not depend upon details. Details should depend upon abstractions
高層模組不應該依賴於低層模組。二者都應該依賴於抽象
(四)練習
1)複數類ComplexNumber的屬性 realPart: 實部,代表複數的實數部分 imaginPart: 虛部,代表複數的虛數部分 2)複數類ComplexNumber的方法 ComplexNumber() 建構函式,將實部,虛部都置為0 ComplexNumber(double r, double i) 建構函式,建立複數對象的同時完成複數的實部,虛部的初始化 getRealPart() 擷取實部 getImaginaryPart() 擷取虛部 getRealPart(double d) 設定實部 getImaginaryPart(double d) 設定虛部 add(ComplexNumber c) 複數相加 add(double c) 複數相加 minus(ComplexNumber c) 複數相減 minus(double c) 複數相減 ComplexMulti(ComplexNumber c) 複數相乘 ComplexMulti(double c) 複數相乘 toString() 把當前複數對象的實部,虛部組合成a+bi的字串形式
虛擬碼:
首先設計一個複數類complex,定義三個構造方法:
①沒有參數時預設為實部和虛部都為0;
②一個參數時預設為實數,即虛部為0,
③兩個參數時分別為實部和虛部
再定義兩個成員方法計算兩個複數的和與差.定義一個print()方法輸出複數的值,當虛部為0時不輸出虛部. 最後定義一個song類使用complex類,在這個類的主方法中建立兩個複數對象,分別計算這兩個複數的和與差並輸出.
public class Complex {
private int sh,xu;
Complex(){
this.sh=0;
this.xu=0;
}
Complex(int sh){
this.sh=sh;
this.xu=0;
}
Complex(int sh,int xu){
this.sh=sh;
this.xu=xu;
}
public void addFu(Complex p1,Complex p2){
System.out.println("這兩個複數的和為:");
this.sh=p1.sh+p2.sh;
this.xu=p1.xu+p2.xu;
print();
}
public void minusFu(Complex p1,Complex p2){
System.out.println("這兩個複數的差為:");
this.sh=p1.sh-p2.sh;
this.xu=p1.xu-p2.xu;
print();
}
public void outputFu(){
System.out.println("複數的值為:");
print();
}
public void print(){
if(this.xu>0){
System.out.println(this.sh+"+"+this.xu+"i");
}else if(this.xu<0){
System.out.println(this.sh+""+this.xu+"i");
}else{
System.out.println(this.sh);
}
}
}
(3)測試代碼
二:總結單元測試的好處:
在單元測試活動中,軟體的獨立單元將在與程式的其他部分相隔離的情況下進行測試,可以尋找錯誤、寫出高品質的代碼、提高編程水平。
它還可以使代碼可以放心修改和重構、使程式員從調用者而不是實現者的角度設計軟體模組、使程式員將軟體模組寫得易於測試和調用,
從而有利於解耦、測試本身可作為被測代碼的用法說明,從而替代了一部分文檔功能。
三、遇到的問題及解決方案
定義源檔案中的Junit測試案例,電腦老是提示java4必須有java5.。。解決方案:將進行百度,和反覆嘗試。
四、實驗收穫
本次實驗讓我瞭解到Java代碼不是像我們想象的那麼簡單,為了代碼的一次性的方便準確,我們應該寫出三種代碼:虛擬碼、產品代碼、測試代碼,這樣的程式才更加方便使用。
運用好單元測試對以後自己的java編程很有好處,應加以熟悉和掌握。
實驗二 Java物件導向程式設計