標籤:
實驗二 Java物件導向程式設計實驗內容1. 初步掌握單元測試和TDD2. 理解並掌握物件導向三要素:封裝、繼承、多態3. 初步掌握UML建模4. 熟悉S.O.L.I.D原則5. 瞭解設計模式實驗要求1.沒有Linux基礎的同學建議先學習《Linux基礎入門(新版)》《Vim編輯器》 課程2.完成實驗、撰寫實驗報告,實驗報告以部落格方式發表在部落格園,注意實驗報告重點是
運行結果,遇到的
問題(工具尋找,安裝,使用,程式的編輯,調試,運行等)、
解決辦法(空洞的方法如“查網路”、“問同學”、“看書”等一律得0分)以及
分析(從中可以得到什麼啟示,有什麼收穫,教訓等)。報告可以參考範飛龍老師的指導3. 嚴禁抄襲,有該行為者實驗成績歸零,並附加其他懲罰措施。4.
請大家先在實驗樓中的
~/Code
目錄中用自己的學號建立一個目錄,代碼和UML圖要放到這個目錄中,中沒有學號的會要求重做,然後跟著下面的步驟練習。
實驗儀器:
名稱 |
型號 |
數量 |
PC |
MacBook(win7) |
1 |
虛擬Linux系統 |
實驗樓虛擬機器 |
1 |
一、實驗步驟
(一)單元測試
(1)三種代碼:虛擬碼、產品代碼、測試代碼
舉例說明:需求:要在一個MyUtil類中解決一個百分製成績轉成“優、良、中、及格、不及格”五級製成績的功能。
a.虛擬碼
百分制轉五分制:
如果成績小於60,轉成“不及格”
如果成績在60與70之間,轉成“及格”
如果成績在70與80之間,轉成“中等”
如果成績在80與90之間,轉成“良好”
如果成績在90與100之間,轉成“優秀”
其他,轉成“錯誤
b.產品代碼
c.測試代碼
運行顯示成功,說明產品代碼此處沒有錯誤
測試一般情況:
運行顯示成功,一般情況下產品代碼沒有問題
測試異常情況:
測試邊界值:
運行顯示未考慮得分100的情況,修改產品代碼:
自此程式碼完成
(2)TDD(Test Driven Devlopment, 測試驅動開發):先寫測試代碼、再寫產品代碼的開發方法
一般步驟:
- 明確當前要完成的功能,記錄成一個測試清單
- 快速完成編寫針對此功能的測試案例
- 測試代碼編譯不通過(沒產品代碼呢)
- 編寫產品代碼
- 測試通過
- 對代碼進行重構,並保證測試通過(重構下次實驗練習)
- 迴圈完成所有功能的開發
用TDD的方式重新編寫百分制轉五分制的例子,感受有測試代碼的好處
a.在Eclipse中單擊【File->New->Java Project】建立一個TDDDemo的Java項目
b.在項目名TDDDemo上右鍵,在彈出的菜單中選定【New->Source Folder】建立一個測試目錄test
c.在test目錄上右鍵,在彈出的菜單中選定【New->JUnit Test Case】建立一個測試案例類MyUtilTest
d.在測試案例類MyUtilTest中,輸入測試代碼,如
e.紅叉說明代碼存在語法錯誤,因為MyUtil類還未建立,類中的percentage2fivegrade方法也不存在;
在TDDDemo的src目錄中建立一個MyUtil的類,建立percentage2fivegrade方法,則測試代碼沒有語法錯誤了;
在MyUtilTest.java上右鍵,選擇【Run as->JUnit Test】,效果
f.測試結果出現了紅條(red bar),說明測試沒通過;
修改產品代碼MyUtil.Java如,再如上一步運行測試代碼,顯示綠條
**TDD的編碼節奏是:
- 增加測試代碼,JUnit出現紅條
- 修改產品代碼
- JUnit出現綠條,任務完成
g.增加測試異常情況的用例testException和測試邊界情況的用例testBoundary,運行測試代碼出現紅條;
修改產品代碼,再運行測試代碼出現綠條
(二)物件導向三要素
1、抽象
(1)對事物表象因素的捨棄和對本質因素的抽取
(2)“去粗取精、化繁為簡、由表及裡、異中求同”的抽象能力決定程式員的程式設計能力
(3)抽出事物的本質特徵而暫時不考慮他們的細節
(4)抽象包括過程抽象和資料抽象
2、封裝、繼承與多態
(1)物件導向的三要素:封裝、繼承、多態。
(2)物件導向的思想涉及到軟體開發的各個方面,如物件導向分析(OOA)、物件導向設計(OOD)、物件導向編程實現(OOP)。OOA根據抽象關鍵的問題域來分解系統,關注是什麼(what)。貫穿OOA、OOD和OOP的主線正是抽象。
(3)OOD中建模會用圖形化的建模語言UML(Unified Modeling Language),UML是一種通用的建模語言,實驗中使用umbrello進行建模
(4)過程抽象的結果是函數,資料抽象的結果是抽象資料類型,資料抽象是OOP的核心和起源
(5)封裝實際上使用方法將類的資料隱藏起來,控制使用者對類的修改和訪問資料的程度,從而帶來模組化和資訊隱藏的好處;介面是封裝的準確描述手段。
舉例說明:
a.Java中用類進行封裝,比如一個Dog類:
b.Dog類通過使用類和存取控制隱藏了屬性color,開放了介面setColor(),getColor(),bark()和toString。Dog類是一個模組,我們可以通過下面的代碼使用它,測試代碼與運行結果如下
c.可以用UML中的類圖來描述類Dog:開啟shell,在命令列中輸入umbrello,開啟UML建模軟體umbrello;
單擊工具列上的類表徵圖,再在class diagram(類圖)中單擊一下,會彈出一個框,輸入類名Dog;
把滑鼠放到Dog類上,單擊右鍵,選擇Properties,在彈出的對話方塊中的Display中去掉Public Only選項;
把滑鼠放到Dog類上,單擊右鍵,選擇New->Attribute,在彈出的對話方塊中的填好Type,Name,並選好Visibility,得到如Dog類
*在UML 裡,一個類的屬效能顯示它的名字,類型,初始化值,屬性也可以顯示private,public,protected。 類的方法能顯示它們的方法名,參數,傳回型別,以及方法的private,public,protected屬性。其中:+表示public;#表示 protected;-表示 private. 使用UML可以讓我們不必關注細節
d.仿照Dog類建立Cat類和AnimalTest類
e.UML類圖要展示類之間的靜態關係,AnimalTest類依賴Dog類和Cat類,UML中依賴用帶箭頭的直線表示
對應代碼:
f.Dog類和Cat類都有Color屬性和相應的set和get方法,違反了前面提到的DRY原則,我們可以通過繼承解決這個問題,把Color屬性和相應方法放到父類Animal中,如以下UML較圖所示:
(注意UML類圖中繼承的標記法,是用一個帶三角的直線指向父類)
g.進一步抽象,把Dog類中的bark()和Cat類中的meow()抽象成一個抽象方法shout(),Dog類和Cat類中覆蓋這個方法,如以下UML圖所示:
(注意UML類圖中的Animal類中的shout()方法是抽象方法,是斜體的,Animal類是抽象類別,也是斜體的)
對應代碼:
(三)設計模式初步
1、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,依賴倒置原則)
(1)OCP是最重要的一個原則,其內容為:
- software entities (class, modules, function, etc.) should open for extension,but closed for modification.
- 軟體實體(類,模組,函數等)應該對擴充開放,對修改封閉。
基於OCP,利用物件導向中的多態性(Polymorphic),更靈活地處理變更擁抱變化,OCP可以用抽象和繼承、面向介面編程手段實現
(2)SRP的內容是:
- There should never be more than one reason for a class to change
- 決不要有一個以上的理由修改一個類
(3)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
- 子類必須可以被其基類所代
- 使用指向基類的指標或引用的函數,必須能夠在不知道具體衍生類別物件類型的情況下使用它
(4)ISP的內容是:
- Clients should not be forced to depend upon interfaces that they do not use
- 客戶不應該依賴他們並未使用的介面
(5)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
- 高層模組不應該依賴於低層模組。二者都應該依賴於抽象
- 抽象不應該依賴於細節。細節應該依賴於抽象
2、模式與設計模式
模式是某外在環境(Context) 下﹐對特定問題(Problem)的慣用解決之道(Solution)。模式必須使得問題明晰,闡明為什麼用它來求解問題,以及在什麼情況下有用,什麼情況下不能起作用。每個模式因其重複性從而可被複用,本身有自己的名字,有可傳授性,能移植到不同情景下。模式可以看作對一個問題可複用的專家級解決方案。
電腦科學中有很多模式:
• GRASP模式
• 分析模式
• 軟體體繫結構模式
• 設計模式:建立型,結構型,行為型
• 管理員模式: The Manager Pool 實現模式
• 介面設計互動模式
• …
其中最重要的是設計模式
3、設計模式實樣本
(1)設計模式(design pattern)提供一個用於細化軟體系統的子系統或組件,或它們之間的關係圖,它描述通訊組件的公用再現結構,通訊組件可以解決特定語境中的一個設計問題。設計模式背後是抽象和SOLID原則。
設計模式有四個基本要素:
• Pattern name:描述模式,便於交流,存檔
• Problem:描述何處應用該模式
• Solution:描述一個設計的組成元素,不針對特例
• Consequence:應用該模式的結果和權衡(trade-offs)
(2)學習設計模式是為了瞭解設計模式可能會存在的過度設計問題以及如何避免它。
(3)除SOLID原則外還有很多其它的物件導向原則。如:
- "組合替代繼承":這是說相對於繼承,要更傾向於使用組合;
- "笛米特法則":這是說"你的類對其它類知道的越少越好";
- "共同封閉原則":這是說"相關類應該打包在一起";
- "穩定抽象原則":這是說"類越穩定,越應該由抽象類別組成";
這些原則並不是孤立存在的,而是緊密聯絡的,遵循一個原則的同時也就遵循了另外一個或多個原則;反之,違反了其中一個原則也很可能同時就違反了另外一個或多個原則。 設計模式是這些原則在一些特定情境的應用結果。因此,可以把設計模式看作"架構",把OOD原則看作"規範"。 在學習設計模式的過程中,要經常性的反思,這個設計模式體現了物件導向設計原則中的哪個或哪一些原則。
(四)練習
1.使用TDD的方式設計關實現複數類Complex
(1)虛擬碼:
複數類Complex
複數的值=a+bi;
加=(a1+a2)+(b1+b2)i;
減=(a1-a2)+(b1-b2)i;
(2)產品代碼:
(3)測試代碼:
二、總結
此次實驗我並沒有很好的完成,前面的幾個任務雖然還是能夠比較順利的做完,但是在後面的編程題目中就顯得心有餘而力不足了。其實一直想學好Java,也知道編程這種東西不是看看視頻看看書,一朝一夕就能學好的,還是要多做題,多練,才能在實踐中總結教訓,學習經驗,希望以後的Java學習能夠有一個很好的突破吧。
實驗二 Java物件導向程式設計