BUAA_OO 第四單元總結和課程總結部落格
本單元的架構設計
第一次作業
作業分析
本次作業需要實現對uml類圖的解析,要求能夠實現類中的屬性和方法的數量統計、類的屬性可見性查詢和類的關聯以及實現介面等等。
架構設計
要完成本次作業,首先要對類圖中各個層次結構進行分析,瞭解類圖中各個元素的關聯關係,如圖所示:
除圖中uml元素之外,還應該由association連線兩個umlClass,每個association含有兩個associationend元素:
在本單元中我自己構造了MyUmlClass
和MyUmlInterfce
類用於儲存類、介面以及其所含有的相應元素,並使用HashMap來儲存各個UmlElement元素,首先進行對所有element元素進行三次迴圈將所有元素加入當相應Map
UMLClass
和UMLInterface
元素,並根據這些元素構造了自己的Class
和interface
類;在第二輪迴圈時,我處理了UMLAttribute
和UMLOperation
等parentId
為相應類與介面的UML元素以及UMLGeneralization、UMLAssociation
和UMLInterfaceRealization
等直接關聯類和介面的UML元素;在最後一輪迴圈中,我處理了UMLParameter
元素。
這個架構結構較為簡單,但在進行部分查詢操作時可能需要時間複雜度較高(但因為本次作業時間限制不是很嚴格就沒有進行太多優化了*_*)
在所有方法中,需要注意的是介面的相關查詢,由於在介面查詢時可能會遇到介面的重複實現,因此,需要使用一個list來儲存已經查詢過的interface,避免因重複實現而造成的死迴圈。
類圖
bug分析
本次作業由於有一個異常丟擲錯誤(即本該拋這個異常的時候丟擲了另一個異常),造成了強測某個點的損失,在改變了丟擲了異常之後bug被順利修復。
第二次作業
作業分析
本次作業要求在上一次作業的基礎上實現對順序圖和狀態圖的解析,並實現狀態機的狀態數量,某個狀態的所有可達狀態,順序圖中的參與物件和順序圖中的訊息等等元素的查詢。
架構設計
本次作業在UML類圖的基礎上添加了UML順序圖和UML狀態圖,為了對UML圖的層次關係進行合理解析,首先需要了解UML順序圖和UML狀態圖的結構關係:
在本次作業中,我添加了MyUmlStateMachine
、MyTransition
和MyInteration
MyInteraction
中等待查詢,比較簡單。在實現狀態圖時,我在MyUmlStateMachine
中儲存了該狀態圖中的所有狀態和狀態轉移關係。除了正常的狀態以外,還有final和init狀態,為此,我在MyUmlStatemachine
中設計了兩個布林變數用於標示該狀態圖中是否含有起始狀態和終點狀態。為了便於狀態轉移關係中觸發事件的查詢,我設計了MyUmlTransition
類儲存與該狀態轉移相關的觸發事件從而進行查詢。
類圖
第三次作業
作業分析
本次作業需要在前兩次作業的基礎上對模型進行有效性檢查,主要包括迴圈繼承、重複實現、屬性同名等情況的判別。
架構設計
在第三次作業中,我設計了一個類FormatCheck
進行有效性檢查。在這些規則中,比較容易出現問題的是R003和R004兩個關於重複繼承和重複實現的判斷問題。由於在資料中可能出現重名的類和介面以及迴圈繼承的情況,我改變了前面搜尋介面時只用name進行判斷的設計,將其改成了用id判斷是否重複,如果前面已經出現過這個id,則說明出現了重複繼承或重複實現等問題,丟擲異常即可。這次作業雖然難度不大,但很容易出現考慮不全面等等問題,幸運的是,由於本單元作業需求改動是漸進性的,沒有出現新的奇怪需求的情況,所以本單元我沒有進行重構,每次作業改動也較少。
四個單元中的架構設計和OO方法理解的演進
第一單元
在完成OO課程所有作業後再回首,我感覺第一單元才是難度最大的一個單元。在第一單元的作業中,由於對面向物件的思維不夠了解,我進行了多次重構以達到三次作業的漸進性需求,最終設計架構的類圖如下所示:
在進行第一單元作業的時候,不管從思路上還是在實現上都遇到了很大的困難,在前兩次作業時,我出現了迴圈依賴的狀況,程式碼複雜度極高,巢狀層數也很深,也因此造成了許多難以處理的bug,在進行重構後,我重新考慮了多項式應有的結構,將其分為了不同的層次進行處理,這樣有效減少了迴圈複用的情況,有效避免了大量bug的發生。
在這一單元我可以說從零開始理解面向物件的思維方法,從第一次作業中面向過程分析整個多項式解析求導的流程到第三次作業將多項式分解為各個層次進行處理,逐漸走向面向物件,我大概瞭解了面向物件的一部分思路——將整個問題拆分成不同部分,每個部分負責自己有關的事情,外部只需要呼叫該部分暴露在外的介面而不會對該部分本身造成改動。雖然第一單元給我造成了非常非常大的壓力,但最終程式的完成給我帶來了很多成就感,也提升了我面向物件程式設計的能力。
第二單元
第二單元的主要目的是為了讓我們接觸多執行緒的相關內容,瞭解多執行緒的死鎖和安全等等問題。比起看到第一單元任務時的不知所措,在這一單元的作業實現中,我很快就找到了思路。在本單元作業中,我採用集中式排程,將整體結構分成了電梯單元和輸入處理單元,每個電梯擁有自己的電梯佇列,當電梯佇列為空時,電梯會從輸入處理單元中的等待處理需求佇列中取得request並放入自己的電梯佇列中進行處理,總體架構如下:
在這三次作業中,我均採用了集中式排程,可拓展性較差,但好處是結構簡單,不容易出現問題。在這一單元作業中,我執行緒安全方面出現了很多問題,作業中經常有死鎖的發生,其中最令我頭疼的是執行緒相互喚醒導致無法進入wait狀態的問題。(執行緒安全問題真的是難發現難解決TAT)經過本單元的學習,我更深入瞭解了執行緒執行機制所帶來的結果——任何兩條語句都有可能連續執行,也就是說,我們必須要保證在任何一種順序下都能夠得到正確的結構,這也是多執行緒程式設計的難點所在。
第三單元
比起前兩單元來說,第三單元真的十分友好,根據課程組給出的JML語言來填充相應函式並作出適當優化即可。在本單元作業中,我將其看成了一個圖模型,person即是圖中的節點,relation是圖中的邊,增加person相當於向圖中增加節點,使用HashMap容器進行存取為了確保一定的時間複雜度避免TLE,我在實現isCircle
函式和queryBlockSum
時使用了並查集機制,為每一個person設定了一個祖先,當兩個person祖先相同時即可說明兩個點聯通,同時在兩個person中新增relation時需要維護並查集的關係;在實現sendIndirectMessage
函式時,我採用堆優化的迪傑斯特拉演算法查詢兩個點之間的最短路徑。
第四單元
第四單元需要實現對UML圖的解析,經過前面三個單元的訓練和學習,在完成這一單元的作業時我對於模組的拆分和梳理已經比較得心應手了,也能快速梳理不同UML元素之間的從屬關係。可以說到了這個單元,我已經能夠較為熟練地應用面向物件的思維方式將整個問題分成不同層次不同部分進行處理了。
總而言之,從第一單元到第四單元,作業難度呈現不斷下降趨勢,我對於面向物件思維方法的理解也不斷增強。從開始時努力從面向過程的思維轉向面向物件的思維到最後一個單元直接以面向物件的思維方式開始思考,將問題拆分為相應部分進行處理,OO這門課讓我收穫許多。
對測試理解與實踐演進
由於對評測機的搭建不夠熟練以及作業已經造成的巨大壓力,我在評測機方面並沒有花費太多的精力,只在某幾次作業中進行了嘗試。在第一單元作業中我嘗試使用python中的sympy庫搭建了對拍程式對互測屋中的程式進行測試;在第二單元中我使用正則表示式生成了部分隨機化資料進行測試;在第三單元中我使用了課程組推薦了JUnit測試方法進行了單元化的測試並使用python程式對一些構造出的邊界資料進行了驗證。在最後一單元中由於直接測試難度較大,我在大佬的幫助下進行了程式的對拍並找到了許多考慮不周全而導致的bug。(此處感謝大佬的幫助)
總而言之,我在測試方面所作出的努力不夠,一方面是因為自身能力不足,另一方面則是因為對測試並不重視,(測試其實真的很重要TAT)我以後會在這一方面多多努力,希望在以後的課程中努力做到完備的測試叭。
課程收穫
-
對面向物件的思維更加了解,將程式看成由一個一個獨立部分組成的個體,由各個個體之間的介面進行協同作用完成程式功能,各個部分之間沒有相互影響,不必知道對方的實現細節。
-
層次化設計能力有所提高,在設計一個規模較大的程式時,可以先進行架構上的設計,並考慮在程式功能需要擴充套件時架構該如何調整。在架構設計完成後可以先將程式碼的框架搭建出來,寫出需要使用的函式和類等待之後填充。
-
資料結構方面的收穫。在每個單元的設計中,我選取了不同的資料結構來適應不同的需求,保證資料存取較為容易。在第三單元作業中,為了保證時間複雜度,我查詢並選用了並查集演算法和堆優化的迪傑斯特拉演算法,對於資料結構方面的知識由了更加深刻的實踐體會。
-
多執行緒方面的知識。在第二單元的學習中,我對於多執行緒執行機制和執行緒安全有了更加深刻的體會,線上程執行過程中,任何兩條語句都可能順序執行,需要使用鎖的機制保證臨界區程式碼的安全。
-
測試方面的收穫。python中subprocess的使用、jar的執行等等。
-
寫程式碼要多做測試,精益求精。在前面幾次作業中,我基本以過中測為目的,在中測完成後就不在進行測試,但在互測和強測的時候往往會暴露出程式碼中的很多問題,在後面的作業中,我往往會更加註重程式本身的質量,多進行測試發現bug,不僅僅是以完成作業為目的了。
總之,OO這門課可以說是我本學期程式設計學習方面收穫最大的一門課了!!!
課程建議
-
建議在寒假預習課程的時候增加一些內容以便更好地和第一單元接軌。(第一單元實在是難度太大了-_-)
-
建議後面兩個單元的題目說明更加完善。在這學期的作業中這JML單元的規格描述和UML單元的敘述存在不清楚的地方,導致同學們需要關注討論區中問題並大量翻閱才能得到明確的說明,甚至在程式碼完成後還需要根據討論區進行改動。(或許可以整理今年有爭議的地方在以後的指導書中明確一下)
-