BUAA-OO Unit4 UML系列
本單元要求實現一個UML分析器,解析mdj檔案資料,對UML類圖、順序圖和狀態圖進行分析,通過輸入指令來進行UML圖中有關資訊的查詢。同時對模型進行有效性檢查,如果模型不符合UML規則,丟擲異常。
1 總結本單元作業的架構設計
本次作業程式主幹邏輯的架構已經非常清晰,採用了層次化設計的方式。在完成介面時,只需要在UmlElement的基礎上實現自己的各個UmlElement類,儲存後續指令需要查詢的資訊和實現方法。
第一次作業
第一次作業是實現類圖解析器。
其中,MyUmlInterface
、MyUmlOperation
、MyUmlClass
是根據對應Umlxxx
下面以MyUmlClass
為例:
-
MyUmlClass
-
Umlclass umlclass
儲存對應的Umlclass類 -
MyUmlClass parent
儲存父類 -
ArrayList<UmlAttribute> attributes
儲存屬性 -
ArrayList<MyOperation> operations
儲存方法 -
ArrayList<MyUmlInterface> interfaces
儲存介面 -
ArrayList<MyUmlClass> associations
-
在UmlLibrary
類中,有HashMap<String, MyUmlClass> classList
儲存所有類和類對應的id。建構函式對UmlElement[] elements
進行分析,當type
屬於UML_CLASS
時,將該類加入classList
中;當type
屬於UML_OPERATION
時,根據parentId
尋找到對應的MyUmlClass
,並將方法新增進MyUmlClass
的容器中。對所有元素進行類似的處理,即可構建起完整的架構,即:
需要注意的是,因為輸入並非按序,有可能方法在類之前出現,因此需要多次遍歷。
第二次作業
第二次作業在前一次作業的基礎上增加了順序圖和狀態圖。
時序圖主要操作是對生命線之間訊息的計數,狀態圖除了計數方法以外,還要求實現getTransitionTrigger
,列出觸發從一個狀態轉移到另一個狀態的事件列表,需要儲存event
和transition
之間的關係。
整體架構如下:
第三次作業
第三次作業在第二次作業的基礎上增加了模型有效性檢查。
建立了有效性檢查類UmlCheck
,實現官方包UmlStandardPrecheck
介面。整體架構上基本和上一次作業相同,其中Uml002檢測迴圈繼承,在處理介面迴圈繼承時,由於一個介面可以繼承多個介面,需要使用dfs找出迴圈繼承鏈。為了確保所有迴圈繼承鏈中的介面均被計算到,我遍歷了所有不在set內的介面,搜尋以其開始並以其結束的路徑,並將路徑內的介面加入set。
2 OO課程總結
總結自己在四個單元中架構設計及OO方法理解的演進
在學習OO課程前,我沒有任何面向物件的基礎,寫過的程式碼都是完全面向過程的程式碼。經過一個學期(困難的)學習,我認為我學到的面向物件並不完全是繼承、多型、封裝這些“面向物件的基本特徵”的實現,而是一種抽象的思想:選取事物的關鍵特質作為屬性,將事物抽象化為類,將屬性和方法組織在類中;將事物之間的關係抽象化為類之間的關係。通過面向物件的程式設計,能夠將一個複雜的系統化整為零、拆分層次,將整體的操作分割為區域性的方法。當然,直到現在我也還沒有能夠很好地理解和運用面向物件的思想,但在開始動手寫程式碼之前,我會留出一些時間去思考如何面向物件地設計架構,實際操作時再根據現實需要做一些修改。總體而言,除了第一單元之外,其他單元都沒有出現重構的現象。
第一單元
第一單元多項式求導,在第一次作業中,我對於面向物件基本沒有多少了解,只採用了正則匹配的方法簡單地寫了兩個類,並且還習慣將很多操作放在同一個方法裡,以及大量的if-else結構,現在看起來這些程式碼十分令人痛苦。後面的兩次作業採用了遞迴下降的方法,第一次嘗試使用繼承,進行多項式->項->表示式因子的逐步轉化,然後再根據表示式因子的種類進行求導。
第二單元
第二單元目的選層電梯,重點是學習多執行緒,通過對共享資料上鎖確保執行緒安全。這個單元開始有意識地去設計一些架構,參考了課上實驗的設計,採用了輸入、排程、執行分離的架構,輸入執行緒將乘客送入等待佇列,排程器對乘客進行分配,將乘客分配到處理隊列當中;每個電梯對應一個處理佇列。等待佇列和處理佇列與兩個執行緒相聯絡,執行緒不能同時訪問共享資料。
第三單元
第三單元JML規格,這個單元不要求自己進行架構的設計,而是需要嚴格地按照JML規格實現方法。實現本身並不難,但由於評測機對時間複雜度有要求,在資料結構的選擇上需要多做一些考慮,對於需要進行大量查詢的資料結構不能簡單地使用容器。同時還學習了一些演算法,例如並查集、Dijkstra演算法的堆優化等。
第四單元
第四單元UML系列,這個單元將層次化體現得很明顯,從互動類到類圖,到類,到屬性和方法,再到引數,從上到下逐次呼叫。在實現的時候我為了方便直接將順序圖和狀態圖儲存在了原先的類圖構造裡,其實不是很合適,類圖、狀態圖和順序圖之間應當做到低耦合。
總結自己在四個單元中測試理解與實踐的演進
在第一單元時,由於時間緊張,只使用了手動構造資料的形式測試了一些極端多項式。第三單元開始嘗試使用一些資料生成程式和與同學程式碼自動比對&計時的程式來進行測試。我使用的程式是完全隨機地生成資料,在研討課上曾經聽到過同學使用函式構造極端資料的方法,顯然比隨機生成資料效率高。但這樣進行黑箱測試並不能完全保證程式正確。在第三單元中,學習了Junit的一些使用方法,通過判斷每個方法的執行結果是否和預期一致來確保方法的正確;如果每個方法都準確無誤,程式的結果自然也不會出錯。
總結自己的課程收穫
經過一個學期的學習,基本能夠了解JAVA面向物件並利用JAVA進行一些較為簡單的開發;瞭解了多執行緒、UML圖等知識;理解了規格對於開發的意義,並能夠根據給出的規格實現方法;能夠比較熟練地使用git進行版本控制;嘗試了隨機生成資料和對拍測試、Junit測試等測試方法。
作為程式設計苦手,在研討課大佬們的分享中也收益良多,非常感謝在討論區、水群和研討課上願意分享自己思路和知識的同學們。
對我而言,OO課的課程設定還是強度比較大的,因為其他課程和工作的緣故,基本上每次作業只有三天左右的時間,在這些時間裡要去學習作業需要應用到的新內容,設計架構,完成實現和測試,時間很緊張,大部分週末都是面對著IDEA度過。但即便是對於我這種並不擅長程式設計的同學,僅僅是跟上OO課進度這件事,就已經能夠帶來許多收穫了。更誇張地說,可以說OO課重新塑造了我的程式設計思維,讓我在程式設計時第一次地把抽象、層次、架構這些概念應用在實踐中。
當然,收穫更多,也會意識到差距更大,未來繼續努力。
立足於自己的體會給課程提三個具體改進建議
-
對於作業的時間限制:個人希望每次作業的釋出時間可以提前一些,適當縮短互測時間,或者互測、bug修復與作業釋出同時進行,這樣可以留出更多的時間來學習新內容和設計架構。每個單元的第一次作業任務量都比較大,要去了解本單元需要用到的新內容,還要設計架構,週三晚上釋出,週四一天滿課,剩下週五週六週日三天的時間會比較緊張。或者提前一週在部落格周釋出一些下單元內容的預告,讓大家提前瞭解相關內容,做一些思考,也會讓第一次作業輕鬆一些。
-
對於作業安排:建議對第一單元的作業做一些改進。對於沒有基礎的同學而言,即便是做了pre,在第一單元作業面前也會感到有些不知所措;特別是第一次作業可以使用正則表示式完成,但由於JAVA正則表示式不支援遞迴,第二次作業必須要更改架構。希望這個單元指導書上能夠增加一點點提示,這樣就可以讓同學們少走很多彎路。
-