注:納斯納斯是阿拉伯傳說里的半邊人,匈古夫同理。標題暗示結對編程中兩個人都發揮對等的作用且不可或缺,並且對一個事物的兩種說法暗示了結對編程中兩人需要通過溝通來確認彼此對同一個事物的看法。
項目 | 內容 |
---|---|
這個作業屬於哪個課程 | 2021春季軟件工程(羅傑 任健) |
這個作業的要求在哪里 | 作業要求 |
GitLab項目地址 | 2021_Ziming_Yang-Jingwen_Tian_pair_work |
學號后四位 | 3080 3420 |
我在這個課程的目標是 | 積累軟件開發經驗,提高工程能力 |
這個作業在哪個具體方面幫助我實現目標 | 體驗結對編程,培養集體意識,提高開發能力 |
一、結對編程感受
這次,我們繼續沿用第一次結對編程所使用的騰訊會議工具,因為它可以實現無障礙的語音交流與屏幕共享,個人感覺比兩個人湊在一起看一台電腦能夠達到更好的交流效果。以下是結對編程期間的截圖

FROM TIAN
在本次結對編程的過程中,我們對於整個過程更加得心應手,在git同步、編程的交流上不需要像第一次那樣花費許多時間,兩個人的溝通質量也得到了更進一步的提高,比如第一次我還經常在思考”他為什么要這么寫,這和我的習慣不一樣“,從而忽略了代碼正確率以及設計質量等更深一步的東西,但是第二次,我們已經可以在大部分跳過理解這步,直接進行設計上的溝通。
同樣的,在對於結對編程的作用上,我也有了更進一層的真實體驗。第一次的時候還會抱着“這個東西這么簡單,就是麻煩了一點點,我自己也可以寫的”想法,但是到了第二次,整個的體系雖然並不沒有復雜多少,但是各種細節的處理上卻是彎彎繞繞、令人頭疼,所存在的問題也永遠比發現的多,這也導致了我們花費大量的時間在測試上。這個時候,更能體現兩個人結對的好處。對於所有問題的解決,都是經過我們共同討論后的結果,這樣明顯能比一個人所考慮得更加全面,同時在討論的過程中,也能進一步提高修改的正確性以及必要性。
FROM YANG
本次結對編程相比於上次的體驗式,更接近於壓力式(盡管這個壓力式可能是指導書的全面性的缺失而導致的)。盡管本次指導書的內容較上次指導書內容較少且用戶系統部分較簡單,但是軟、硬鏈接的出現,讓目錄樹變成了目錄圖,mv和cp方法的出現,目錄和文件在目錄樹中的位置不再是靜態的了。這使得本次項目的邊界情況多的令人發指,再加上“不再贅述”所導致的不能單純看某指令的對應內容來編寫該指令的代碼,使得我在結對編程的過程中逐漸煩躁,且思路愈發混亂。好在有領航員及時幫我梳理思路,才不至於陷入泥淖無法自拔。
除了上面所說的感受,這次我們對結對編程的整體流程更加熟練,溝通效率更高,構建了了“1看指導書->2實現指令->3發現問題->4提出 issue->5解決問題->1”的 pipeline,實現了端到端的閉環流程。
二、設計實現思路
在完成本次的文件管理系統的增量開發前,我們首先對上次的設計進行了修改。一是異常拋出的位置,我們重新規定只能在MyFileSystem
和Parser
的方法中拋出異常,這樣的規定能使我們的編碼邏輯更加清楚,在調試的時候也不會出現忘記拋沒拋出異常、在哪拋出異常的問題。二是我們重寫了Parser
中的方法,更加確定了它作為解析類的作用,使其只完成解析工作且盡量解析完全。三是為了提高時間效率,我們將原來的先獲取文件對象、后獲取其上級目錄對象的邏輯,改為先獲取其上級目錄對象,然后根據其目錄對象直接在目錄樹中獲取此文件對象。
對於本次的增量設計,我們了延續了上次的架構和思路,建立新的硬鏈接文件HardLinkEntry
類和軟連接文件SoftLinkEntry
類,仍使FileSysEntry
類來作為目錄類和所有文件類的父類,同時,考慮到新增要求,在其中添加統一屬性(user_name、group_name、count),並使文件類的getCount
方法恆返回1。
對於硬鏈接和軟鏈接的設計,我們采用”硬鏈接鏈接到文件,軟鏈接鏈接到路徑“的思想,分別在硬鏈接中存儲所鏈接到的文件對象,在軟鏈接中存儲所鏈接到的絕對路徑。對於它們的重定向操作,我們選擇建立一個Redirectable
接口,使SoftLinkEntry
和HardLinkEntry
均需實現此接口的redirect()
方法。
此部分的UML圖如下

對於redirect()
方法的實現,在硬鏈接中,直接返回其所鏈接到的文件對象;在軟鏈接中,使用FileSysEntry
的find
方法根據其鏈接到的絕對路徑在目錄樹中找到其對應的文件/目錄,同時,為了在FileSysEntry
中訪問目錄樹,我們將MyFileSystem
中存儲的根目錄設為公共靜態變量。
同時,由於硬鏈接的size
實際存在,而fwrite
和fappend
會更改文件的大小,此時也應該通知鏈接到其的硬鏈接的上層目錄更新size
,考慮到硬鏈接與文件多對一的關系,我們在文件類中新增hardLinks
列表,存儲所有鏈接到其的硬鏈接,並在文件大小更新時通知列表中所有的硬鏈接。
對於用戶系統的實現,我們新建了用戶User
類和用戶組Group
類,分別在用戶和組類中設置公開靜態root
對象,代表最初存在的root用戶和其存在的主組。對於用戶和組之間的多對多的關系,我們分別在User
類中存儲其所在的groups
列表,在Group
類中存儲其包含的users
列表,便於訪問查詢。
在MyUserSystem
類中,我們設置了groups
列表存儲所有的已建組,同時,為了便於用戶的查詢,我們同樣在其中存儲了所有用戶的users
列表。
此部分的UML圖如下

對於用戶系統和文件系統的交互,我們參考了issue區中所提供的方法(【討論】用戶系統和文件系統如何交互),利用單例模式,創建一個單例類Manager
,在其中設置myFileSystem
和myUserSystem
屬性,在文件系統和用戶系統的構造方法中分別為其賦值,這樣,我們就能夠通過SystemManager
在兩個類中互相獲取其方法/屬性。同時,考慮到指令數變量的公有性,我們將其的位置也由FileSystem
改到了SystemManager
中,便於兩個系統的調用。
這樣,對於exit
命令中的獲取上一次su
命令時用戶所在的工作目錄需求,我們就可以在進行su
操作時通過SystemManager
中的myFilesystem
獲取當前工作目錄的絕對路徑,進行存儲,並在執行exit
命令時,更新myFileSystem
中的當前工作目錄。
同樣的,對於文件系統中新建文件/目錄時,需要的當前用戶和其所在用戶組的信息,也可以通過SystemManager
中的myUserSystem
獲得。
此部分的UML圖如下

對於異常的設置,為了設計架構的清晰性、便於調試,我們將過程中可能出現的異常做了區分,並對第一次的異常情況進行了適當調整,最后區分為MyFileSystemException
和MyUserSystemException
,分別繼承課程組給出的異常抽象FileSystemException
類和UserSystemExceotion
類。

最終架構如下

三、PSP表格記錄
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 30 | 30 |
· Estimate | · 估計這個任務需要多少時間 | 30 | 30 |
Development | 開發 | 770 | 1250 |
· Analysis | · 需求分析 (包括學習新技術) | 30 | 20 |
· Design Spec | · 生成設計文檔 | 30 | 30 |
· Design Review | · 設計復審 (和同事審核設計文檔) | 50 | 60 |
· Coding Standard | · 代碼規范 (為目前的開發制定合適的規范) | 0 | 0 |
· Design | · 具體設計 | 60 | 120 |
· Coding | · 具體編碼 | 360 | 360 |
· Code Review | · 代碼復審 | 60 | 90 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 180 | 570 |
Reporting | 報告 | 90 | 110 |
· Test Report | · 測試報告 | 30 | 30 |
· Size Measurement | · 計算工作量 | 30 | 20 |
· Postmortem & Process Improvement Plan | · 事后總結, 並提出過程改進計划 | 30 | 60 |
合計 | 890 | 1390 |