1. 程式人生 > 其它 >OO Unit4 單元總結

OO Unit4 單元總結

OO 第四單元總結

1. 總結本單元作業的架構設計

本單元的目的是通過自己的方式儲存 UML 圖中的元素,並實現特定的查詢指令。

由於輸入輸出介面已經由官方包實現,我主要考慮的就是資料的儲存方式以及查詢時的遍歷方式。

類圖

根據類圖中不論繼承還是屬性、方法的從屬關係都是單向的,我選擇了採用樹狀的結構了儲存與類圖有關的元素。
對於絕大多數元素,我都建立了類來對其進行儲存,而對於 UmlGeneralizationUmlInterfaceRealization 這兩種用於表示繼承和實現關係的邊,我沒有建立與之對應的類,而是通過將他們標記的 “父” 和 “子” 之間建立聯絡,具體來說就是在子類(介面)中儲存了父類(介面)的指標。而父類中並沒有掌握任何關於子類的資訊,這也符合 java 中的情景——父類(介面)並不知道哪個類繼承(實現)了它。
對於 UmlAttribute

UmlOperation 我直接在類(介面)中儲存了他們的指標,而 UmlOperation 中又儲存了 UmlParameter 的指標,從而形成了樹形的結構,便於從類開始向下查詢。
最後,由於 關聯關係 的儲存邏輯並不符合樹形結構,我又單獨建立了 MyUmlAssociation 類,並在其中儲存了官方包中的 umlAssociationEnd 類,對應的類可以通過其中的 ID 找到其關聯的對端。進而進行相應的查詢操作。
類圖部分設計的類的類圖如下:(略去了不重要的一些屬性和方法)

順序圖

由於順序圖中查詢指令的種類較少,設計到的元素也不多,所以我只將 UmlLifelineUmlMessage

兩個元素抽象成了類,並用 MyUmlInteraction 來承載這兩個元素。
MyUmlInteraction 中,由於對 UmlLifeline 的查詢是根據名字進行的,故用 Map 來承載數個 UmlLifeline 。而對 Message 的查詢是要求遍歷輸出個數的,且需要分別處理收到和發出的訊息,故在 UmlLifeline 中用兩個 ArrayList 來分別承載收到的訊息和發出的訊息。
這部分的類圖如下:

狀態圖

狀態圖部分很符合圖論中關於有向圖的定義,所以我在實現時也是通過圖的方式來實現的。此外還有兩個比較特殊的類,UmlStateMachineUmlRegion

其中前者是狀態圖的頂層模組,後者是狀態圖中的 ”畫布“ 在本次作業中,一個狀態機只有一塊畫布,所以我將 UmlStateMachine 最為了一箇中介,主要作用是進行狀態圖的初始化,具體的節點和邊都儲存在 UmlRegion 中。
具體的實現方法是:
MyUmlState 中存與狀態相關的資訊,MyUmlTransition 中存狀態轉移的起點和終點以及相應的 guard 和 trigger。由於 MyUmlTransition 只儲存了對應狀態的 id,因此,MyUmlState 還需要和其對應的 MyUmlRegion 進行通訊從而獲得其能夠轉移到的狀態的引用。
這部分的類圖如下:

2. 總結自己在四個單元中架構設計及OO方法理解的演進

  1. 第一單元:多項式求導
    經過 pre 的訓練,在進入第一單元時,我已經由了架構設計的意識。在本單元中,將多項式的各個部分組織成了樹狀結構,這樣的架構使得我在進行表示式解析的時候可以比較輕鬆的將輸入轉化為我設計的資料結構,在求導時也可以通過向下依次求導來快速獲得結果。但是這樣的設計的問題就是在進行表示式化簡時會比較繁瑣,一旦處理不好還容易出現 BUG。

    在本單元中,我對 OO方法的理解還僅限於最基礎的 封裝、繼承、多型的概念。
    而通過這一單元的學習,我最大的收穫是明白了 OO 只是一種方法,和其他方法比起來,是各有優劣而不是絕對優越的,所以即使在 OO 課程的作業中,適當的使用面向過程的程式設計方式也可以很好的化解問題。此外,我還了解了通過繼承關係對類進行管理在很大程度上簡化程式。

  2. 第二單元:電梯
    在這一單元中,我們初步接觸了多執行緒程式的設計。

    在本單元中,主要的任務是處理多執行緒的安全問題。具體的電梯控制方式,我採用的是分散式控制,絕大部分操作都是由電梯執行緒自己根據公共佇列中的資訊自主決定。電梯間的競爭使得最終的結果相對優越。

    本單元的學習讓我對面向物件的設計方式有了新的理解,瞭解了類之間的溝通與協作的方式,瞭解了執行緒安全相關的設計模式(如生產者消費者模式)

  3. 第三單元:JML
    這一單元我們主要在學習規格。

    這單元的題目比較簡單,可以使用鄰接表法來儲存圖關係,通過圖論中學習的演算法來對圖中的元素進行遍歷與查詢。需要注意的是本單元對效能的要求比較高,所以在進行查詢操作時要時刻注意自己的演算法複雜度。

    本單元的學習讓我理解了測試在 OO 程式設計中的重要性,瞭解了測試驅動開發的方法。

  4. 第四單元:UML
    關於本單元的架構設計在上面已經解釋過了,在此不再贅述。

    本單元讓我理解了在進行程式設計時可以採用畫 UML 圖的方法來進行建模,從而幫助程式編碼,使編碼更加快捷,正確性也會得到提高。

  5. 總結
    通過 OO 課程的學習,我對 OO 方法的理解從“封裝,繼承,多型” 三要素開始逐步加深,依次理解了層次化設計,多執行緒設計,物件間通訊的方法,基於規格的設計和基於模型的設計。
    通過這些作業我還理解到,OO 只是眾多程式設計方法中的一個,而程式設計不存在最優解,不存在所謂的 “銀彈” ,在進行程式設計時我們需要根據自己的需求來選擇一種或多種適合的方法來輔助自己達成目標。此外,OO 方法也不僅僅是一種程式設計方法,在管理現實中的事物時,採用 OO 方法中的一些套路也可以事半功倍。

3. 總結自己在四個單元中測試理解與實踐的演進

  1. 第一單元:多項式求導
    在這一單元中,驗證自己多項式求導的正確性可以通過 Python 中現成的庫函式。因此在本單元的作業中,我通過編寫測試指令碼執行特定的測試用例來驗證自己的程式結果是否正確。
    在此時,我對測試的理解還淺顯的停留在了用樣例來測試程式的階段,所採用的測試樣例也大多是來自於隨機自動生成,還不能根據自己程式的特點構造有針對性的測試樣例,也沒有采用單元測試的測試手段。
  2. 第二單元:電梯
    在這一單元中,我們初步接觸了多執行緒程式的設計。
    由於多執行緒程式存在執行結果的不確定性,所以我在進行測試時採用了 “壓力測試” 的測試方法,即同時開多個程式來執行,經過我的實驗,開 100 個左右的執行緒可以使我的電腦 CPU 佔用率達到較高水平,使得執行緒不安全的問題更加容易暴露出來。
  3. 第三單元:JML
    這一單元我們主要在學習規格。而規格正是測試程式執行是否正確的方法這一。本單元中,每個需要實現的函式都對前置和後置條件有著嚴格的規定,因而十分適合採用單元測試的手段。
    在這個單元中,我第一次接觸到了單元測試的手段,也是在這作業中,我開始關注採用樣例對程式的覆蓋性。可以說在通過這個單元的學習我才真正開始對 “測試” 有了深入的瞭解。
    除了單元測試,本單元作業對效能的要求也十分嚴格,故在測試時我也會有意識的去構造容易導致 TLE 的樣例,也開始想辦法記錄程式的執行時間。
  4. 第四單元:UML
    作為 OO 課程的最後一個單元,在本次作業進行測試的最大難點就是無法確定正確的結果究竟應該是什麼。為了解決這個問題,我組建了一個對拍小組,大家將每個人的輸出集中在一起進行比對,如果出現了不同的結果,就會在一起討論每個人對題目的理解,直到達成一致。通過這樣的方法,我們攻克了絕大多數的難關。

4. 總結自己的課程收穫

  1. 對 OO 方法的理解逐漸加深
    正如之前提到的,通過這多次程式設計作業和部落格作業,我對 OO 方法的理解逐漸深入
  2. 開始注重在程式架構設計
    OO 課程的作業有迭代開發的需求,所以在動手程式設計前,必須想好程式碼的架構,並且需要為之後迭代開發預留一定的空間,如果不在開始編碼前對架構有一定的設計和思考,那麼在折後的作業中對面臨需要多次重構的窘境。
  3. 瞭解了不同的測試方法
    通過這幾次作業,我瞭解了測試指令碼的編寫,測試用例隨機生成的方法,單元測試的方法,測試點的覆蓋率等一系列測試的手段的標準,也通過 JML 單元的學習初步的瞭解了形式化驗證方法。
  4. 學習了一些常用的設計模式
    通過程式設計作業和課上實驗,我學習到了一些常用的設計模式,比如生產者——消費者模式,簡單工廠模式,單例模式等。
  5. 學習了一些演算法知識
    在第一單元中,我學習了遞迴下降語法分析的演算法
    在第三對應中,我學習了並查集的實現與應用,Dijkstra 演算法的堆優化等演算法
  6. 瞭解了 Java語言的一些語法知識和可能導致隱祕 bug 的實現細節

5. 立足於自己的體會給課程提三個具體改進建議

  1. 希望實驗可以提前公佈一個預告,可以讓我們提前預習一些實驗可能用到的方法。
  2. 希望實驗可以公佈結果
  3. 希望第四單元作業的題目描述能更加清晰,最好可以給出一些邊界情況的樣例和樣例說明,防止大家在討論區大量提問