第一次UML做業的文件樹以下:node
本次做業採用的是分離需求的設計思路,每一類需求整合到對應的類中單獨存儲,並配置修改和訪問方法。web
在頂層,實現課程組提供的UmlInteraction
接口的類MyUmlInteraction
只負責將UmlElement
傳入parser解析,並對外提供查詢接口,剩下處理數據的任務交由parser完成。此外,在此類中還存放有全部UmlElement
的查詢表,並提供全局訪問方法,經過id便可訪問到對應元素正則表達式
MyUmlClassMapParser
類負責解析處理類圖中的UmlElement
,考慮到後續做業會新增順序圖和狀態圖的解析,故將其放在parser包中以便擴展。算法
ClassBlock
類存放了須要查詢的類/接口中的信息(名字取的很差。。把接口和類統稱爲類塊了),其中包括:AssociationInfo
(關聯信息),AttributeInfo
(屬性信息),InterfaceInfo
(接口信息),OperationInfo
(方法信息),這4個需求信息統一歸到infos包中管理。編程
對於用於查詢的各個info類,存放信息使用的數據結構基本上爲HashMap
與HashSet
嵌套使用,且在每一個info類中都或者存放有已查詢過的confirmed
數據表,或者是isConfirmed
的boolean型確認表,其目的都是爲了實現記憶式查詢,如屬性可見性、關聯對端等需求的查詢,在訪問過父類後便可記錄下結果,下次訪問時就沒必要再從新往深層探索,而是直接獲取已有數據,這樣就使得查詢的速度會隨查詢次數的增大而加速。查詢方法採用的算法基本爲遞歸查詢,以便在回溯時記錄數據。windows
如下是本次做業的Uml類圖:設計模式
第二次UML做業文件樹以下:安全
本次做業大部分繼承了上次做業採用的架構,改動的地方是除去了parse包,而將每種UML圖的解析都歸類到單獨的包裏,即classmap包(負責類圖處理),collaration包(負責順序圖處理),statechart包(負責狀態圖處理),並將各個parser放在了對應包的頂層。此外,新增的checker包用於歸類UML規則檢查。數據結構
類圖的處理在第一次做業中已經介紹,在此再也不贅述。順序圖的處理按照UML順序圖的分層方法進行了層次劃分,Interaction
類做爲「畫布」存儲了核心的解析數據,如lifeline,message等(順序圖的畫布Interaction「撞臉「瞭解析器的命名,因此在命名這一環節上處理得不太好),MyUmlCollarationParser
提供解析數據與查詢數據的接口。相似地,狀態圖的處理也按照UML狀態圖的分層方式進行層次劃分,Region
做爲」畫布「存儲核心數據,MyUmlStateChartParser
提供parser功能。
本次的checker包中只有一個MyUmlChecker
類負責規則檢查,一方面是爲了方便,另外一方面也是做爲UML類圖規則檢查劃分到一個類中。若是後續有擴展需求的話,能夠選擇在類中添加方法或創建新的類,按照檢查的維度進行劃分。
如下是本次做業的Uml類圖(與第一次做業相同的內容省略):
做爲OO的最初篇章,腦子裏對「架構」這兩個字並無什麼概念,對於程序的設計仍停留在分析需求、面向過程的編程思想上。固然,對類和對象概念的理解也促使着我在朝着面向對象的思惟方式上轉變。
這一單元的三次做業採用了三種不一樣的架構設計,但設計的思想都大抵一致,也就是將表達式逐層剖離至基本元,再進行求導。第一次做業只分離出了Unit
做爲最基本的求導元,沒有考慮可擴展性,是爲完成需求而設計,利用正則表達式對錶達式進行拆分解析的過程也統一放在Expression
類中。第二次做業的需求直接報廢了第一次做業的設計,雖然還是用Unit
做爲基本元,但對這一基本元類作了重構,將其修改成三元組(x, sinx, cosx)的形式進行存儲,本次做業作了一個新的嘗試是將求導操做抽象爲一個類,在計算時實例化求導對象進行計算。第三次做業的需求又再次顛覆了第二次做業的設計:三元組沒法支持嵌套元求導,故又再次進行了重構,將表達式解離爲多個嵌套表達式,而嵌套表達式又由多個基本表達式和嵌套表達式組合而成,並嘗試抽象出了CombTerm
和Term
兩個接口以顯示本身有在學面向對象,當層次設計完成後,表達式拆分的目的地就比較明確了,求導計算就變成了自頂向下逐層完成任務的過程。
總之,第一單元的體會就是:次次重構次次爽。雖然說這一單元花在表達式解析和WF判斷上的精力比較多,但其實面向對象的思想也有訓練到,尤爲是第三次做業,在設計好層次關係,理清各個層的職能以後,真實地感覺到思路清晰帶來的爽快感。
這一單元親自體會到了多線程的「噁心」之處,但實際上在完成這一單元的訓練以後,會發如今一開始架構設計的大路就已經被課程組鋪好了,剩下的只是怎麼在這條路上走出花樣、走出水平。做爲多線程和設計模式的零基礎學員,只能老老實實循序漸進地「走大道」了。但不得不說的是,接觸了設計模式與設計原則後,已經逐漸可以從面向過程的需求分析思惟,過渡到面向對象的架構設計思惟上去了。
第一次做業十分簡單,老實按生產者-消費者模式代入便可安全經過。第二次做業加上了捎帶的需求,仍然沿用生產者-消費者模式,改進的地方是引入緩衝區供捎帶隊列的獲取,以及電梯內的捎帶算法調整,感受此次做業本身的重點更多地放在調度策略的設計上,而對架構的考慮不是很充分。第三次做業使用了Worker-Thread加觀察者的組合模式,即電梯做爲工人獲取請求並處理,調度器存儲外部請求,並能夠登記或移除電梯。對於換乘的設計,採用「換乘港口」的思路,將請求送至港口後就做爲新請求送入調度器。
這一單元對設計模式的瞭解使得架構設計在必定程度上變清晰了(雖然內部調度處理仍是讓代碼變得很難看。。。)。對SOLID設計原則的考慮也進一步規整了設計,而不只僅停留在「完成需求」的要求上了。
這一單元的訓練重點是JML規格語言的理解和代碼功能的迭代設計(其實我感受重點更偏向圖論和數據結構。。。)。不過令我滿意的一點是,這三次做業的重構範圍比較小,基本上是在沿用上一次代碼的基礎上根據需求進行增添,這或許是能力提高的一個表現?
第一次做業沒有創新,只實現了官方的接口就能通關。第二次做業在實現接口的基礎上增長了MyGraphCalc
類用於處理圖的相關計算。第三次做業按照功能將類劃分入了三個包,即calculator,container和raildata包,分別表明計算模塊、頂層容器模塊和地鐵系統中相關數據模塊。計算模塊負責圖結構或地鐵系統中的相關計算;頂層容器模塊負責提供路徑、圖、地鐵系統的修改與訪問接口;地鐵系統中相關數據模塊將地鐵系統中須要查詢的信息分爲幾個模塊(連通塊、最少票價、最少不滿意度等),每一個模塊中完成指定信息的修改、存儲與訪問接口的提供。
總的來講,這一單元算是複習了一遍數據結構和圖論,但不知不覺地,本身也對架構的設計有了要求,而且這是一個良性的過程,設計考慮得越周到,編碼消耗的時間就越少,bug也容易定位。
這一單元的架構設計已經介紹,故再也不贅述。從第一單元的設計嘗試,到第四單元認真地思考哪種設計能更好地實現需求,而且對可擴展性、耦合度、魯棒性都有必定的考量,對架構設計的理解算是有些小進步吧。但要想設計出優秀的架構,如今的能力還相差甚遠,還需進一步在練習中不斷學習。
測試確實是軟件設計中不可或缺的一個環節,每次做業看到中弱測全過期,心裏就會產生一種錯覺:個人程序已經沒有bug了!然而強測一片紅時又會開始悔不當初:爲何當初很差好作測試?在一學期四個單元裏,測試方法由肉眼法到寫對拍器,再到Junit測試,算是測試實踐的逐步演進。每次通過充分測試後,內心就會十分踏實了,而若是再被糾出bug,這些bug就再也不是粗枝大葉致使的bug,而成爲值得回顧反思的「優質bug」。
第一單元對測試不是很上心,測試的方法是比較原始的肉眼查bug,不管是對本身的程序仍是互測屋中的程序,測試的精力放在輸入輸出的檢測上,對於求導的邏輯就沒有過多的關心。在第三次做業時實現了對拍器,算是測試方法的一種改進,但實際上有了對拍器後就更懶得看代碼了。。。研討課上同窗分享的觀點值得反思:「互測的目的並非‘找到’,而是‘去找’。「
第二單元的電梯做業,因爲是多線程設計,測試起來就更加困難了,在本身的程序測試中採用的是IDEA中自帶多線程Debug方法。在互測屋的測試中實現了定點投放數據腳本,但沒有實現對拍器和數據生成器,所以只能以肉眼觀察找數據爲主,定點投放爲輔,配合使用進行測試。
第三單元真正接觸了Junit,體驗極佳!尤爲是看到代碼覆蓋率和本身代碼欄左側密集的綠條時,心裏十分知足安心。此外,寫完Junit測試程序後,每次測試只需一鍵,很是方便,能夠輕鬆定位到bug出現的位置,即便找到邏輯錯誤,進行必定範圍的修改後,也一鍵測試也很方便檢測這次修復的bug是否會影響到以前測試點的經過率,避免出現「修復1個bug長出10個」的狀況。
第三單元還接觸了JML規格檢查以及JMLUnitng自動生成測試樣例等JML有關的測試方法,這些方法雖然在理論上十分強大,但目前好像並非很「智能」,期待之後的發展。
第四單元的測試仍沿用Junit的測試方法,但發現寫Junit測試程序也須要耗費必定的精力,尤爲是在課程組提供官方接口的狀況下,測試樣例的編寫就比較困難,也許是我尚未發現樣例編寫的捷徑?
總之,在測試方面也算是有了些收穫,也意識到了測試的重要性,往後還須要在這方面上下足功夫。
本學期對於OO的訓練量,說多也很少,說少也很多。很少的緣由是獨立設計出的架構還遠沒有達到OO所要求的質量,很多的緣由是這學期確實在摸爬滾打中走來,也有了很多「本身的東西」。
從各個單元實際內容的收穫來看,第一單元學到的是正則表達式解析表達式與表達式的處理,第二單元是多線程程序設計與電梯調度,第三單元是JML規格語法與圖論,第四單元是UML模型的理解。經過對各類問題的分析,以及階梯式的問題難度和測試,對於各種程序設計問題都有獲得必定的訓練。
從各個單元的設計目標來看,雖然沒有徹底達到目標,但在接近目標的過程當中也有不小的收穫。第一單元的目標是 「構造抽象層次,進行歸一化處理「,在將表達式逐層解析的過程當中,也在鍛鍊將問題抽象分解的能力。第二單元的目標是 」識別線程及共享數據,控制共享安全「,因爲初次接觸線程安全,即便通過三次難度遞增的做業的訓練,對線程安全的理解還只停留在比較基礎的階段,對一些線程控制方法並不能很好的融匯貫通,不過可以完成協調多個線程工做的任務,也算是一大收穫吧。此外,設計模式的學習也提供了架構設計的模板,這些模板並不必定要生搬硬套,理解這些設計模式後相信對本身的設計能力會有很大幫助。第三單元的目標是 「根據功能須要適應性能要求的中間數據模型和協同架構」,第三單元雖然說是以JML規格語言爲主題,關注的重點更多的是如何讓本身的圖結構算法不被RTE,三次做業依次地逐層構造以及複雜度的增長,對架構設計的可延續性與性能的考慮能力有所提高。第四單元的設計目標是 「針對諸多不一樣類型的對象構造層次和關係,構造模型過程當中動態維護相關查詢數據」,這一單元給出了各個對象原型,訓練的是如何將這些對象按照其屬性特徵、功能結構進行分層、整合,從而更好地協同工做。
整體來看,這一學期收穫到的是面向對象程序設計思惟與架構設計能力的入門卡。不得不說,一個好的設計架構所帶來的編碼體驗是不言而喻的,體驗到架構設計的魔力之後,將來對一份需求的設計就會更加上心,運用合理的架構設計思惟去分析需求所得到的效果。以及,課程收穫到的仍是強大的抗壓能力:中測wa掉一個不可見的點不管怎樣都測不過,即便心態爆炸也要含淚繼續debug;在有限的ddl以前若是架構崩壞,須要有狠下心重構的勇氣;強測爆炸即便很沮喪仍要笑對bug修復。。。
感謝老師、助教、討論區大佬們這學期的幫助與貢獻!祝願OO課程越辦越好🎈🎈🎈(這學期體驗其實挺不錯