1. 程式人生 > 其它 >{name:"面向物件第四單元UML系列總結部落格",type:"UmlBlog"}

{name:"面向物件第四單元UML系列總結部落格",type:"UmlBlog"}

面向物件第四單元UML系列總結部落格


前言

經歷了與OO相愛相殺的一個學期,真的是感慨萬千。此時再讀一讀自己的部落格和程式碼(可惜前面的程式碼已經看不懂了)還是很有成就感,這個學期開始的時候多多少少還是聽到過OO的許多傳聞,對這個新的學期感到有些害怕,不管怎麼說自己還是堅持了下來。經歷過深更半夜重構程式碼到兩三點的折磨,也有著因為前面作業架構做好了之後順風順水的輕鬆與喜悅,也有五一假期作業輪空了一次身心的空虛與寂寞,課程的最後拿到了狼人獎(這個是真的沒有料到,我感覺我還是非常人畜無害的^_^)和暖心分享獎,也是對自己的一種肯定。OO課教會了我如何高效自學新知識,如何設計架構,如何測試,以及保持良好的程式碼風格,這些訓練都無形中教會我一個優秀的工程師應當具備的素質。

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

本單元的架構設計比較清晰,都採用了層次處理的設計架構,即每一個層次只需要管理其直接下屬的元素。本次作業的CPU時間放的比較寬,於是在提高效能上並沒有採取很多的方法,基本上使用了快取的思想和部分優化演算法。

第一次作業

第一次作業是解析類圖中的元素,本次作業中,針對其中的UmlXXX的在Java中擁有實體的類建立了MyXXX的類,共劃分為三個層次:

Layer1 Layer2 Layer3
MyClass,MyInterface MyOperation,MyAttribute MyParameter

對於UmlAssociation、UmlGeneralization等表徵類圖中關聯、泛化等關係的類,對這些關係類本身沒有儲存的必要,所以沒有對其建立自己的類,只需要把這些類所表示的關係,記錄到上表中相應層次的實體類中即可。本次作業相較於第三單元的最大不同是,圖的構建和圖的查詢是時間上嚴格分離的

,所以執行相應的查詢時,遞迴的時候路徑節點將本節點的查詢結果快取,方便再次查詢時加快查詢速度。

第二次作業

第二次作業與第一次作業架構基本相同,添加了時序圖和狀態圖的部分元素,並且將狀態圖的解析與構建解耦成為一個單獨MyParser類,時序圖與狀態圖的相關作業需求並不是很複雜,只需要嚴格按照UML的規則實現即可。

第三次作業

第三次作業是對UML模型進行簡單的有效性檢查,仍然按照從上到下的層次進行有效性檢查,演算法上在解決含有多繼承的介面的迴圈鏈查詢的問題中,使用了拓撲排序的演算法。在有效性檢查中,有許多關於重複的判斷,由於之前的架構中,大量使用了HashSet和HashMap等的自動去重的容器,導致本次作業又使用ArrayList進行了大量的冗餘儲存,使得本次作業的架構並不是很簡潔明瞭。

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

雖然一個學期的課程結束了,但是如果讓我僅僅抽象的說我對OO的理解,仍然感到還是有一定的困難,封裝、繼承、多型這些固定的說法並不能夠體現出我對OO的理解,如果讓我談一談我對OO的理解:抽象是重要的,迭代是必要的。實現物件化的方式並不複雜,更多的是讓自己的實現能夠為擴充套件預留空間,讓自己的每一部分儘可能地為後面的部分所複用。巨集觀設計與具體實現要相互補充,巨集觀設計不一定要每個細節面面俱到,在具體的實現中隨著自己對問題域的瞭解更加深入進而調整自己的結構設計。通過UML與JML,這個思維與實踐交替的過程也被很好的解耦了,這是一種OO的很好的體現,通過UML在靜態的模型層面進行嚴謹的描述,同時也能夠暫時忽略一定的細節,在模型的指導下,根據需求設計出滿足需求的規格,實現的時候只需要關注規格,這流水式的開發過程也是OO的非常生動的體現。

第一單元

第一單元初識OO,第一次基本上還是按照解決問題的步驟和流程,以過程式的思維來思考的,遇到哪些功能可以放到一個類,就把這些功能整合在一起,類僅僅是順手將一些資料與函式放在一起的聚合體,沒有資料或功能上的內聚。後兩次作業,有所感覺,根據表示式的層次化結構,將各種運算抽象出來,將各種運算門抽象為類,每個運算的類只需要完成這個運算的求導操作。格式檢查,求導,化簡時比較獨立的三個板塊,所以應當為每個板塊建立一個相對獨立的層次,三個板塊之間只需要共享部分資料。

本單元中每個物件要實現一定的功能與資料的內聚,不同的板塊之間最好要有清晰的界限。

第二單元

第二單元電梯系列的執行緒安全是重中之重,我基於對共享資料的分析,對臨界區程式碼都使用了synchronized()進行同步互斥,採取了電梯執行與乘客排程分離的架構,電梯完成乘客的請求,排程器專門對乘客的請求進行分派,電梯執行緒使用了狀態模式進行建模。

這一單元最重要的執行緒安全設計,在我看來執行緒安全是一個面向物件中一個不可避免的矛盾,每個類都假設自己獨佔資料,只關心自己的資料如何處理,不會主動關心整個環境所處的狀態,而整體的功能正常實現卻需要各個類的協作與互動才能夠實現,這個矛盾的存在,使得程式設計師必須讓不同的執行緒在時序上同步與互斥,確保按照一定的執行序列執行。執行緒安全設計相當於在物件化的世界中建立的一種法規,例如紅綠燈的出現,正式為了保證行人和車輛只能互斥訪問交叉路口,這樣的規則的構建應該獨立於物件,要在一個更高的層次上來規劃與設計。

第三單元

第三單元的沒有太多的巨集觀架構的考慮,更多地是如何選擇資料結構將JML中的規格以更低的複雜度實現,在本單元,許多類的實現是為了方便建立某些特殊的資料結構,方便對資料進行管理。這一單元更多啟發我規格的作用,本次作業中許多方法只需要按照規格就可以無腦地實現,這種方便與快捷也大大地說明了規格與實現分離是一種非常優秀的OO思想,能夠讓我在實現的時候能夠更加專注於資料結構與演算法的選擇,而不同特別的關心架構問題。

第四單元

第四單元更多的是層次化處理,將UML的層次化結構在自己的程式碼中體現出來。在本單元中,我採取了獨特的設計,每個類需要管理每個類所需要的資料之外,頂層類對於所有的物件的存在都是可監視的(上帝視角),但是頂層類對所有物件只讀不可寫,這樣的好處是頂層類在實現不同層次的類的互動時可以起到橋樑的作用,但是對資料的實際管理還是落實到了每個具體的類。這也提示我們高內聚低耦合不是簡簡單單的內聚越高,耦合越少便是好的,適當的耦合可以使得互動更加方便,而且對整個程式的結構沒有很大的破壞,在處理實際問題的時候,這些OO設計原則不應當生搬硬套,要與自己的業務邏輯緊密結合,達到最好的權衡。

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

通過一個學期的課程,也提高了許多測試相關的能力,隨著作業的演進,我學會了寫資料生成器,對拍機,自動化測評工具,從一個人寫到多個人協作開發,測試效率越來越高,對強測也越來越有信心。

第一單元

本單元主要採取手動構造極端資料,使用python進行正確性的判定。

第二單元

本單元通過按照一定策略生成乘客請求,並通過書寫正確性判定邏輯進行正確性的判定。

第三單元

本單元通過一定策略生成資料,通過對拍進行正確性的判定。

第四單元

本單元主要通過手動構造UML模型生成資料,通過對拍進行正確性的判定。

測試雖然沒有明面上在課程設定中體現出來,但是強測的高質量測試資料真正地驅動我們進行高質量的測評。測評從單打獨鬥到協作開發,也讓我認識到真正的開發過程中團隊協作的重要性,通過交流與合作,能夠更好地對資料的極端情況進行挖掘,也減輕了個人的工作量,提高測試的效果。

總結自己的課程收穫

能夠熟練地使用Java語言進行一定規模的開發,學會了使用git進行版本管理(上個學期計組如果也使用git我也不會起那麼多長長的檔名了......),學會了測評資料的生成與對拍機的實現。

OO課有很多交流,通過交流能夠碰撞思維的火花,能夠結交友誼。這個學期和許多同學討論過一些作業的問題,雖然很多都是線上交流討論,並沒有見過面,但是不影響對技術進行深入的交流與探討,從他人身上得到一些新的啟發,或許以後見過面可能會說:“原來您就是xxx,幸會幸會(久仰久仰)——”。

OO課更多的是一門哲學課(好吧哲學課怎會會有WA和TLE呢),通過OO課掌握了物件化的程式設計思想,更多的教會了我一種認知與解決問題的方法論,層次化,模型化,併發設計這些思想不僅在程式設計上發揮作用,在生活的方方面面也能夠找到影子。

OO的部落格作業非常有意義,特別是對於我這種表達能力不是很強的人,通過部落格不僅能幫我梳理自己的思路,總結教訓,提取經驗,也能夠鍛鍊我的表達能力,如何讓其他人通過你的部落格瞭解的思想,在程式設計師世界這個高度開放的社群,寫部落格的能力非常重要,優秀的部落格和程式碼一樣,能夠成為自己的一張名片,體現個人的能力。

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

關於實驗課

建議每次實驗課前提前釋出一下本次實驗課的實驗內容,這樣課下能夠做一定的準備,不至於實驗課對著大量的程式碼發呆,例如GC的那一次課上實驗,建議提前釋出一個內容讓我們先自學一下比如實現一個Demo,不至於課上只寫了一個僅僅能夠通過樣例的程式碼就可笑地認為自己寫對了。

關於課程節奏

一週的課程安排可以說是無縫銜接,體驗非常良好,但是我認為還可以再改進一下,週一週二的互測階段其實互測本身花費不了那麼多時間,(卷王除外),互測階段我都會根據我對本次作業的易錯點的預判讀一讀程式碼,如果沒有很明顯的錯誤,剩下的就基本上交給測評機了,一個晚上的時間足矣,而且週三晚上才釋出作業,週三白天的時間相當於閒置了,建議作業釋出和互測同時開始,這樣能夠有更多的時間理解並實現作業。

每個單元最難受的基本上都是第一次作業,我在完成第一次作業的時候除了要關心架構設計,還要學一些本單元特有的基礎知識,例如第二單元花了一整天的時間才理解了同步互斥的含義並學會實現一個簡單的Demo,留給作業的時間就比較少了,感到比較吃力,建議把每個單元的第一次作業與上一個單元的部落格作業同時釋出,這樣能夠有更多的時間理解下一個單元的內容。

關於作業內容

JML和UML兩個單元的作業難度相較於前兩個單元確實小了許多,但是作業完成起來非常煎熬。JML要實時關注討論區對程式碼和JML的修改,UML單元指導書有許多表意比較模糊的點都要通過討論區來加以確定,總之一點都不乾淨利落,耗費了很多時間。

個人建議後兩個單元指導書如果沒有大幅的改動,前一屆的討論區可以整理成一份資料傳給下一級,畢竟針對同樣的表述,大家產生的疑惑也應該大致相同。JML和UML兩個單元主要對JML和UML的理解做的比較多,並沒有真正寫JML,也沒有用UML進行模型的設計,很難真正認識到JML與UML的威力,建議這兩個單元可以淡化對演算法的考察,增添一些對JML和UML本身的訓練內容。UML單元可以訓練一下用UML準確描述一個工程的模型,但是這一部分最大的難度是怎麼給同學們進行考評。