Object-Oriented Programming Summary Ⅰ

 

 

17373492  Beihang University


Part 0: 前言

使人聞風喪膽的OO仍是來了。並無像名字的外表同樣可愛,簡直就是惡魔。java

瘋狂壓榨OS的時間,週末沒法休息,互測狼人機制正則表達式

雖然網上罵聲不少,就算改進到9012年仍是有不少不足的地方,但和往年相比,已經有很大進步,也更加人性化了,咱們並不能力求在咱們這一屆作到完美,這畢竟是一個長期長期長期長期又漫長的過程。既來之,則安之,既然沒法改變規則,就讓本身適應規則吧。架構

 

Part 1: 量度分析

接下來將細分開每個板塊來對我本身的三次做業來進行分析ide

DesigniteJava

DesigniteJava是一款專門分析代碼質量的靜態評估工具,而且識別潛在的質量問題。它會檢查代碼的架構,設計和代碼的異味而且以csv的格式給出詳細的度量分析。函數

對與分析Java這種面對對象的語言,咱們此次主要看這幾個參數:工具

  1. CC 圈複雜度性能

    用來衡量一個模塊斷定結構的複雜程度,圈複雜度越大說明程序代碼質量低,難以測試和維護學習

  2. LCOM 方法的內聚缺少度 值越大說明類內聚合越小測試

  3. FANIN 類的扇入 扇入表示調用該模塊的上級模塊的個數,扇入越大,表示該模塊的複用性好。優化

  4. FANOUT 類的扇出 扇出表示該模塊的直接調用的下級模塊的個數,扇出大代表模塊內複雜度高,但扇出太小也很差。

    總結就是,一個好的JAVA代碼,設計要求是高內聚低耦合的,因此LCOM值要小,FANIN的值要大,FANOUT值合理。

     

    那麼用這個方法看三次的度量結果:

     

    第一次做業:

第二次做業:

第三次做業:

 

能夠發現,在Main函數中咱們的圈複雜度都是相對較高的,這是由於我在Main中放了存放和預處理字符串的代碼,這致使圈複雜度增高,並且確實大量的正則表達式和字符串替換難之後續閱讀和維護,這是毋庸置疑的。看了其餘同窗的優秀代碼,好比17373331的代碼,Main中幾乎沒有什麼實際的執行代碼,只是在調用其餘方法和處理異常,看優秀的代碼給個人感受就是很是清晰,在主函數中就明確告訴我了這個project是在什麼的,合理的類的命名,簡單易懂的返回值設定和處理異常的語句,符合OOP的設計。

果真,沒有對比就沒有傷害:17373331的靜態分析:

 明顯能夠看出參數飽滿了不少,不像我生成的幾乎都是0,較小的LCOM和較大的FANIN和合理的FANOUT,果真花花的代碼能被稱做標杆範文。
 
此外,能夠看到個人代碼分析後的FANIN是幾乎沒有的,說明個人代碼的複用效率低下,可能存在不少重複的代碼,反觀個人代碼確實在這幾回做業中,確實有不少服用的代碼,就好比字符串爲了防止被查WF,反覆用正則表達式檢查變換幾回,甚至用上了 while (matcher.find())這樣的循環查找,不只複用率低下,其實代碼的執行效率也很是低下。

  反思本身的代碼質量,幾乎慘不忍睹,甚至感受用來查c等面對過程的語言獲得的結果也相差無幾,主要是如下幾點緣由:
  1. 閱讀面對對象的代碼太少,學習了理論可是沒法本身親手時間,可能具有了閱讀不一樣的代碼說出是否是符合面對對象的設計,可是本身卻沒法寫出。

  2. 對質量的盲目追求。在分數的利益驅動下,天然地用面對過程的語言,也就是本身熟悉的語言來處理字符串,這樣雖然代碼不是很好看,甚至在第三次做業中爲了判斷各類WF狀況而寫了冗雜的正則表達式查詢代碼,致使主函數內方法函數超60行,代碼風格質量嚴重下降,這時又只能經過分開創建不一樣的方法來分擔正則式的長度,惡性循環致使風格逐漸降低,可是分數能夠很好,別人幾乎不能攻擊個人WF,這也是對本身的代碼風格和分數之間的trade-off之間,分數佔了上風吧。

  3. 尚未造成剝離抽象層的思惟,像zsa學長在討論區的接口講解很是清晰,舉出了生動的例子——手機的充電接口來讓咱們理解。 可是老是在本身構思的時候就沒法剝離出sin cos 和x 和constant 之間的共性特徵和共性方法,因此也不多使用繼承或者藉口了,在最後一次的做業中強制要求使用後才嘗試用接口的方法來解決求導的問題。

接下來查看本身的UML圖,由idea自動生成:

第二次做業UML



第三次做業UML

第一次做業彷佛沒法生成UML,多是由於太面向過程了一點,但我還能夠看到第二次和第三次的,可是要我評價本身的類圖,我十分羞愧,由於這徹底是一個沒有上過OO理論課的人都能寫出來的東西,因此我大概講一下個人類圖在寫代碼時的構造吧:

在第二次的代碼中我才用了四元數的方式,因此本身構建了兩個class,分別是Trig 三元組儲存x 和 sin 和 cos,還有Term 四元數在三元數的基礎上增長了前面的常數項,由這兩個class咱們就能夠對相同的相進行合併。而且嘗試了多態的方法;在第三次的代碼中採用了接口的方式,對全部項的求導進行了歸一化,可是其實能夠更加優化,那就是將全部的項歸併到抽象類中,由於他們都有共同的屬性好比內部的表達式(指sin和cos內部的值)還有冪次都是共通的,用抽象類的方法能夠將他們更加內聚在一塊兒,因此我也打算從新寫一遍第三次的代碼了,固然是創建在閱讀第二次優秀的代碼基礎之上。

在第三次做業中,我也對static和final有了更進一步的瞭解。以前看到java的代碼中不少的static因此沒有融入本身的思考盲目static,這直接致使我第二次做業開始,開的類多了以後出現致命的錯誤,建立多個對象以後共同修改一個屬性,致使了大片的錯誤輸出,因此說仍是實踐出真知。

Part 2: bug分析

第一次做業:

第一次做業比較簡單,固然本身用面對過程的語言作因此沒有出什麼問題,最後是數據點全過+0hacked,可是固然還有美中不足的地方,那就是性能分沒有拿到滿分,具體在於本身運用HashMap的方式存儲結果,查詢不到HashMap如何查找到特定value的值,即正數的值放到第一位,因此最後性能分未滿,可是若是如今要我再交的話,我會利用先存進ArrayList的形式來作一個簡單的排序,從而將正項第一個輸出。

第二次做業:

第二次做業在強測中出了一個BUG,致使被分配到了C組中去,由於本身優化太過於匆忙,疏忽了HashMap在puts以前要先檢查是否存在,致使相同的Key值出現了覆蓋Value的狀況,最後失分。其實本身寫了一個專門puts進HashMap的方法,在方法中檢查了Key值並進行合併,可是因爲是ddl前的早上優化因此沒有進行太多的測試,過了弱測和中測就沒有多想,這個案例說明 僥倖心理 是萬萬不可取的。

在互測屋中還被發現了一個特殊的bug,在輸入以運算符結尾的時候我不能判斷出格式錯誤,致使被人狂刀,這也是和本身的測試策略有關,本身在自測的過程當中偏向於對正確性進行檢驗,而忽略了錯誤形式的表達式的構建,致使失分。

第三次做業:

吸收了第二次做業被WF殺害的經驗教訓以後,幾乎最後一天都在對格式判斷進行改動,可是沒有注意到助教的置頂帖中已經說明移除了WF的數據,有一點時間沒有用到刀刃上的感受,甚至有點把本身給誤傷了。過多的特殊WF狀況的判斷致使本身對代碼的結構已經沒法理解,結果在強測中對正確的輸入報了WF,痛失去一個強測點。此外,對括號內的處理也不夠仔細,忽略了冪次也能帶有負號的問題,致使表達式提取出現問題,結果丟分。

 

在第一單元最後一次的研討課上,有位同窗給予了咱們一個開始工程的思路——先構建數據集(測試集),再下手打代碼,起到打代碼的時候有的放矢的高效。開始的時候我是有點不理解的,可是在反思本身的做業的過程當中,發現第三次做業中我所犯下的錯誤徹底是能夠由一開始構建一個較爲完備的測試集而規避的,並且紀老師說在後續的工程化代碼中,提早構造測試集是一種很是有效防止嚴重漏洞的手段,因此我也考慮在重寫第三次做業的時候也嘗試這種方式。

 

Part 3: hack

對於查找別人的漏洞的方式,主要在於如下幾點:

  1. 本身在打代碼的時候,測試本身的代碼時所出錯的數據點都一一保留,這應該是算弱測。

  2. 尋找特殊的表達式的特徵,具體多是x-x或者多個+-號的形式。

  3. py或者java自動生成代碼加上mma的帶入測試。

  4. 尋找同窗進行求助,每一個人對同一問題的思考角度不一樣,hack別人的點通常有很大區別,因此是一個補全的很好的策略。

 

Part 4:重構的說明

重構其實不是一件丟人的事情,自從上學期計組以來,發現其實解決本身bug的最好最快的方式就是重構。重構能夠幫助咱們在原有的基礎上進行改善,一方面驗證咱們對現有知識體系的更加深層的理解是否正確,另外一方面也是對將來增添功能時候提供一種方便。在初學的階段,我認爲重構代碼時很是常見的,也是一種高效的學習方式,雖然時間會花費不少,因此在第二次做業中我就採起了重構的方式,改掉了原有的面向過程的寫法,採用了初級入門的面向對象,而且在第三次做業中也複用了第二次做業的體系邏輯,雖然增添刪改了許多內容但其實也減輕了我挺大的工做量的。

 

以上即是本人對於前三次OO做業的博客總結,後續可能會貼上本身第二次做業甚至第三次做業的優化的方法的思考。

相關文章
相關標籤/搜索