一. 本單元兩次作業的架構設計 終於在最後一個單元實現了增量式開發。在本單元第一次作業中,我便構建了圖數據結構,第二次作業變得比較簡單,無需重構,只是增加狀態圖和順序圖即可,下麵分析第二次作業的架構設計。 1. 頂級類 MyUmlGeneralInteraction 負責將輸入歸類,形成3個子Uml ...
一. 本單元兩次作業的架構設計
終於在最後一個單元實現了增量式開發。在本單元第一次作業中,我便構建了圖數據結構,第二次作業變得比較簡單,無需重構,只是增加狀態圖和順序圖即可,下麵分析第二次作業的架構設計。
1. 頂級類 MyUmlGeneralInteraction 負責將輸入歸類,形成3個子UmlElement數組,分配給處理類圖,狀態圖和順序圖的3個類;
2. 建立基礎設施類:graph,實現圖的通用方法:加邊,dfs,計算可達結點,拓撲排序等。對於類圖,類和介面都當作圖中的結點;
3. MyUmlClassModelInteraction處理類圖,MyUmlCollaborationInteraction處理順序圖,MyUmlStateChartInteraction處理狀態圖,三者基於graph類;
4. 狀態,遷移個數抽象成圖的結點數和邊數,後繼狀態抽象成計算圖中某點的可達結點數;
5. 參與對象,交互消息抽象成圖的結點數和邊數, incoming消息抽象成圖中某個結點的入度;
6. 有了圖結構之後,類圖中的函數實現也變得非常簡單。比如計算類實現的全部介面實質,先做拓撲排序,再按照逆拓撲序依次計算每個結點實現的介面。這樣一來,計算某個類時,其父類,以及其實現的介面實現的介面都已經算出來了,直接列表相加就行。不需要任何的遞歸。
7. 建完3個圖後,將所有的查詢全部計算完畢緩存起來,之後查詢只是訪問緩存結果。
二. 四個單元中架構設計及OO方法理解的演進
1. 表達式求導系統
由於已經有設計和實現編譯器的經驗,本單元作業我直接寫了一個小型編譯器。求導過程可看作是一個翻譯過程:源語言:原表達式,目標語言:求導後的表達式。比如第三次作業指導書上對於item的要求看起來複雜,但拆成一個個小單元後,很容易就能寫出item的文法,之後採用遞歸下降分析法,一次掃描,同時完成了格式檢查和求導的工作。我設計和實現的求導都是形式求導,實質是字元串的拼接。思路和實現都很簡單。在實現的過程中,我對於java的記憶體分配與釋放,淺拷貝以及函數參數和返回值的傳遞等都非常迷惑。通過課下閱讀《java編程思想》,我也算較為深入地理解了java語音以及OO的思想和具體實現形式:封裝,多態,繼承。
考慮到擴展性和易實現性的均衡,我選擇了易實現性,導致我第三次作業直接重構,沒有做到增量式開發。
2. 電梯調度系統
三個線程:電梯,調度器,主線程(輸入線程), 採用worker thread,生產者消費者模式。main向request中放入請求,調度器從request中拿出請求並分配給一個電梯(放進該電梯的task處),電梯從自己的task中拿出請求並執行,car是電梯的轎廂,代表電梯內的請求。此種實現方式不是電梯去向調度器要任務,而是調度器主動分配任務給電梯。整個架構耦合度較低。
在這次編寫併發程式的過程中,我不僅學會了註意線程安全性(多個線程互斥訪問臨界資源),還學會了註意多線程對共用變數的可見性,而後者往往容易被人忽略。《java併發編程實踐》這本書對並非編程講得非常好。
以前在上操作系統的時候,直接用c去實現簡單地併發調度非常困難。而java面向對象的併發編程方式,是如此的優雅與易用,大大降低了併發編程的門檻。
本次作業涉及多個對象之間的交互,我使用了面向對象的繼承和介面。
3. 地鐵調度系統
最初,我對JML充滿了好奇,非常敬佩這種契約式思想。但之後慢慢意識到,JML承諾得太多,但最終能夠使用的功能卻很少,且非常難用。這也是其沒有大規模流行起來的原因吧。
本次作業的核心是建立自帶緩存功能的graph。雖然整體架構已給出,我們只需完成少量代碼,但如何將實際需求抽象成圖還是花了好長時間去思考。如何緩存,如何降低時間複雜度,如何以空間換時間,如何均勻分配負載都是值得思考的問題。
這次作業雖然實現了增量式開發,沒有重構,在寫第三次作業的時候對於第二次作業已有的代碼我一行都沒動,只是在MyGraph類裡加了求連通塊個數的Public的函數。這樣一來bug少了,但新加的架構和已有的架構看起來很不協調。
4. UML解析系統
這次作業我學習了UML的建模思想。那麼在實際開發中,UML是否可以代替自己手工繪製的架構設計圖,是不是大家都只畫UML來進行交流,不會使用自己隨便畫的架構圖。這是一個我有疑問的點。
三. 對測試理解與實踐的演進
想要輕鬆通過強測,一個自己構建的強大的測試機是必不可少的。
1. 表達式求導系統
使用正則表達式生成測試樣例,再輔以精心構造的邊界測試點。但沒有構建自動化的測試程式,導致測試成本高。
2. 電梯調度系統
這次構建了自動化的對拍程式,通過電梯運行的特定規則來判斷結果的正確性。
3. 地鐵調度系統
手工構建了一些比較特殊的測試樣例,併進行了壓力測試。
4. UML解析系統
構建並和同學交換了測試樣例,眾人拾柴火焰高。實現自動化對拍腳本,將自己的結果與其他人的結果進行對拍實現測試。
四. 課程收穫
1. OO的思想
回過頭來看,這學期一共輸出了1萬行的java代碼,還是感覺到不可思議。OO使編寫具有規模的程式變得更加容易。每次寫完,除過幾個簡單的bug外,代碼幾乎很少有bug。與之相反,過程化編程的bug非常得多,在上學期寫編譯器的過程中,我對過程化編程的大量bug的感受尤其深刻。
OO是一種看待世界的思維方式,沒有了上帝視角,組成系統的每個基本元素管好自己的事情,整個系統將井然有序,能夠實現非常複雜的功能。
2. java
真切地感受到了:學習一門編程語言的最好方式就是在做中學。語法稍微瞭解一下即可上手,做中學使學習過程更加高效和深刻。
五. 改進建議
1. 架構設計。雖然經歷了這麼多次作業,但我覺得自己架構設計的本領還遠遠不夠。建議增加一個專註於架構設計的的單元,沒有編碼。通過學習大量經典的架構設計案例和親手設計高效的架構,達到之後看到類似本課程每一次作業難度的架構設計時,能夠在短時間快速給出一個高效架構的本領。
2. 增加討論區搜索的功能。討論區帖子特別多,但沒有搜索功能,很難定位到自己想找的帖子。
3. 建議專門在指導書中加一部分對於細節,對規則具體解讀的章節,尤其對於之後像第四單元最後一次作業類似的作業。使得需求更加清晰,明確。