天天看點

軟工——淺談“建構之法”

軟工——淺談“建構之法”

問題 内容
這個作業屬于哪個課程 2021春季計算機學院軟體工程(羅傑 任健)
這個作業的要求在哪裡 個人閱讀作業2要求
我在這個課程的目标是 提高個人開發水準以及團隊合作意識
這個作業在哪個具體方面幫助我實作目标

閱讀《建構之法》了解課程目标

調研源代碼版本管理軟體和持續內建/部署工具

讀書小結

在看到《建構之法》的書名時,我以為會是一本講系統架構的技術書籍,但後來翻閱的時候發現并非如此。我閱讀的是第三版,相對于前兩版,作者删減了不少章節,反而重點叙述了很多軟體工程中的實戰内容。雖然我個人暫時沒有參與過大型軟體項目的工作,但是在讀到很多章節時卻能奇妙地産生一些共鳴。該書沿用了《移山之道》中的一些人物,包括大學生、研究所學生或者剛工作幾年的技術人員,通過人物之間的對話和活動生動形象地還原了軟體開發中可能出現的場景,這也是這本書讓讀者覺得更加真實熟悉的原因。

由于時間原因我并沒有完整的看完此書,隻是選擇性地進行翻閱,也希望自己在日後的學習工作中遇到疑惑時再回頭翻閱這本書能有更深刻的體會和更大的收獲吧。

閱讀提問

1、結對程式設計是否有大規模應用的可能

在結對程式設計中,因為有随時的複審和交流,程式各方面的品質取決于一對程式員中各方面水準較高的那一位。這樣,程式中的錯誤就會少得多,程式的初始品質會高很多,這樣會省下很多以後修改、測試的時間。
在結對程式設計中,任何一段代碼都至少被兩雙眼睛看過,被兩個腦袋思考過。代碼被不斷地複審,這樣可以避免牛仔式的程式設計。(《建構之法》4.5.2)

就軟體工程這門課來說,結對程式設計可能是從鍛煉大家與他人的溝通交流以及合作開發的能力出發進而開設的項目。但是從行業整體來看,結對程式設計似乎并沒有進行廣泛應用。文中提到“程式品質取決于一對程式員中各方面水準較高的那一位”以及“結對程式設計迫使程式員必須頻繁交流,而且要提高自己的技術能力,以免被人小看”。雖然由這種假設所推導出的結論是美好的,但是我個人認為這裡的假設有些過于理想化。

  • 在現實中公司以“結對程式設計”的形式迫使員工提高個人技術能力未免顯得成本有些過于高昂,甚至在兩人水準差距過大的極端情況下可能出現一方始終在學習而另一方始終在工作的狀态。
  • 如果雙方水準差不多,結對的效果與一方寫完代碼後另一方進行測試的團隊模式好像沒有明顯差別。這樣看來未免有些為了結對而結對的意味。

其次“代碼”被不斷地複審雖然會使最終代碼的品質有所保證,但是除非是一個緊急項目,否則所花的人力與時間成本應該是遠遠大于後期測試成本的。在結對程式設計與兩人合作部落格中舉了很多網際網路技術的重大突破都是由兩人完成的執行個體,但是如果仔細研讀就會發現并不是所有人都适合結對程式設計,換句話說,這些人的成功跟他們自身的特性密切相關。或者兩人所學專業恰好互補且在各自的領域都有很深的造詣,或者合作時間很長并且堅持相同的信念等等。如果沒有這些偶然,結對程式設計對我們日後的發展是否有很大的借鑒意義呢?

2、單元測試是否一定要程式員自己編寫

軟體的很多錯誤都來源于程式員對子產品功能的誤解、疏忽或不了解子產品的變化。如何能讓自己負責的子產品功能定義盡量明确,子產品内部的改變不會影響其他子產品,而且子產品的品質能得到穩定的、量化的保證?單元測試就是一個很有效的解決方案。(《建構之法》2.1)
單元測試必須由最熟悉代碼的人(程式的作者)來寫。(《建構之法》2.1.2)

前文中說道“軟體的很多錯誤都來源于程式員對子產品功能的誤解、疏忽或不了解子產品的變化”,說明很多錯誤是由于程式員的個人原因造成的,甚至自己都沒有意識到相關子產品的錯誤。就個人而言,做測試時我隻會測試自己考慮到的情況,與寫程式時自己的思路不會有太大改變,當時沒發現的錯誤測試時由于邏輯漏洞也很難發現。是以即使自己很熟悉代碼,但是因為思維慣性就很難跳出自己設的陷阱,如果換别人反而可能在更短的時間内找出bug。

在很多設計課程中,同學們可能會互相分享測試資料增強自己程式的魯棒性。這裡先将自動生成單元測試排除在外,如果僅靠大家自己測試可能很難發現自己程式的漏洞,但是我們又往往能在他人提供的資料中能發現錯誤。況且單元測試一般隻是測試一個程式的部分功能,與對程式的熟悉程度沒有太大關聯,是以,如果程式員自己有時間當然可以編寫測試程式,如果沒有時間也可以通過文檔描述自己程式哪些地方思路不太完善讓測試人員做重點測試應該也不失為一種可行的辦法?

3、測試人員的要求

阿超:一個商業項目,請不要讓連開發語言都沒有接觸過的隊員進行開發工作。并不是非得“寫”程式才是對項目有貢獻,有時不寫也有很好的貢獻。如果他們有熱情,就從測試開始學習吧。(《建構之法》11.8)
阿超:開發人員的代碼沒寫好,可以依賴于測試人員來發現問題。但是如果測試人員的代碼沒寫好,我們依賴誰來測試和改錯呢?這就要求我們測試人員的代碼品質特别高,因為測試人員是最後一道防線,如果我們的代碼和測試工作有漏洞,那麼Bug就會跑到使用者那裡去。(《建構之法》13.3.1)

讓“連開發語言都沒有接觸過的隊員”不要進行開發工作說明了寫程式這一步驟在項目中的重要地位,這當然是無可厚非的,但是讓他們從測試開始學習是否就說明測試工作允許犯錯的幾率更大呢?那後文中的“測試人員是最後一道防線”說明項目對測試人員的代碼品質要求也很高,而且測試人員要對他人的代碼應該需要很強的洞察力,這也是建立在自己強大的程式設計和邏輯基礎之上的。我們不願意讓小白擔任開發又怎麼能願意讓他做與客戶連接配接的最後一道防線呢?

誠然無論是測試還是開發,如果能寫出高品質代碼當然最好,但是如果沒有過硬的技術又更适合擔任哪一類職務呢?測試人員的硬性标準又該是什麼呢?

4、最成功的創新是在拿手領域之外發現的?

我們不就是為了成為某個領域的專家,才來上學,拿學位,希望拿到學位之後成為專家,然後再開始這個領域的創新?但是統計資料表明,70%的創新者說,他們最成功的創新,是在他們的拿手領域之外發現的。(《建構之法》16.1.5)

對這個觀點我不太認同。什麼叫“拿手領域”呢?因為阿裡巴巴的創始人馬雲大學大學畢業于杭州師範學院外語系,是以我們認為他的拿手領域是外語嗎?從馬雲的早年經曆看似乎并非如此:1994年馬雲與來自西雅圖的外教聊網際網路并開始尋找機會創業,1995年他去了西雅圖第一個ISP公司VBN參觀,同年3月他從學院辭職,同年4月,中國黃頁正式上線。到1999年,馬雲團隊回到杭州又開始了新一輪創業,開發阿裡巴巴網站。在此過程中,我們可以認為馬雲抓住了時代的機遇,但我們并不能認為網際網路不是他的拿手領域,即使他不是科班出生,但他為此付出的努力以及最終的成就足以說明他的确“拿手”。

特定領域的教育的确能大大提升我們某一方面的專業素養,但與此同時各個領域之間并非界限分明。當今很多行業需要多領域人才融合發展,就如同網際網路行業光靠本專業的技術人才是遠遠不夠的,需要有一些架構人物幫助推動行業的整體發展,跟拿不拿手以及所學專業無關。

5、關于使用者體驗的慣性

使用者在網上送出資訊,通常會看到兩個相鄰的按鈕,【送出】【取消】,這樣簡單的設計仍有很多可以改進的地方,例如有下面的建議。(《建構之法》12.1.5)
軟工——淺談“建構之法”

關于提高使用者體驗方面,該書提到了例如可以将意義相反的選項間隔拉大或者采取不同的樣式,降低使用者誤操作的可能性,這是一種簡便但不失有效的方法。但與此同時,我想使用者為什麼會誤操作呢?比如在我們個人電腦上有時會出現一些廣告彈窗,我們會習慣性地點選右上方關閉,但往往這裡的按鍵會把廣告直接打開,後來費了很大力氣把它關掉後發現真正的關閉鍵設定在彈窗的左上方。

當我們習慣使用某個功能後往往會産生一定的思維慣性,如果被一些人加以利用,即使沒有太大損失,也會對我們使用産品的流暢性造成較大的困擾,這裡又該如何避免呢?是否需要上升到制定一些行業規範的高度來控制此類行為呢?

6、創新者困境

如果公司不斷滿足已有使用者需求,則産品在趨于飽和的市場緩慢發展,在産品的生命周期結束後,不免會被新的颠覆性創新淘汰;如果公司主動尋找颠覆性創新,則遭到公司内部流程、價值觀和文化的排斥(《建構之法》16.1.7)

文中提到“颠覆性的創新會帶來産品和市場的巨大風險,這些企業中的流程、價值觀和文化會排斥颠覆性的創新”。的确颠覆性的創新會有巨大風險,後文中也舉例說明了這一觀點,但是成功的企業之是以成功就是因為當年的颠覆性創新,當市場成熟後,成功的公司一定會主動尋找新的創新點,而不是坐以待斃。更何況成熟的公司已經具有雄厚的資金和人脈,在創新産品後有更便捷的推廣管道,也能承受相關的一些風險。而一些小公司雖然可能帶有颠覆性創新,但是在産品推廣的第一步可能就困難重重,一旦某個環節出現差錯可能整個公司都完蛋。

我們現在看到一些成功的小公司都是在層層篩選下運氣和機遇都恰到好處的公司,那些創業失敗的案例我們又能接觸到多少呢?成功企業的創新可能性是否應該比小企業要大些呢?

7、關于極限程式設計

所謂極限程式設計,就是把一些認為重要和有效的做法發揮到極緻。(《建構之法》6.4.1)
軟工——淺談“建構之法”

我對于表格中部分發揮到極緻的做法有些困惑。左欄中的做法看起來都是重要且有效的,但是到了極緻似乎就有些“偏離正道”。

  • 每時每刻都有客戶在身邊——首先這條件似乎比較難以實作,其次雖然客戶需求在實時變化但如果事先不盡量細緻了解客戶總體要求就可能會需要連續重構,放在課程中可以鍛煉我們的程式設計能力,放在工作中恐怕就不太合适了,會增加大量的時間和人力成本。
  • 别做詳細的設計,做頻繁的增量開發、重構和頻繁地釋出——與上文類似,即使計劃沒有變化快,但這是否就意味着我們可以沒有計劃呢?頻繁地釋出所耗的資源與做詳細的設計耗費的資源哪一個更多呢?

調研源代碼版本管理軟體

關于GitHub、Gitlab、Bitbucket等源代碼版本管理軟體的異同:

相同點(基礎特點):

  • 拉取請求
  • 代碼審查
  • Markdown支援
  • 進階權限管理
  • Fork / Clone Repositories
  • 第三方內建

不同點:

  • GitHub:開源協作的首選。目前GitHub上擁有全世界最大數量的公共開源項目,全球頂級科技公司(Google / Apple / Facebook 等)都加入GitHub,全球頂級開源項目(Linux / Nodejs / Swift 等)都優先選擇在GitHub上開源。
  • 關于導入的代碼倉庫類型不同:GitHub支援導入Git,SVN,HG,TFS. GitLab支援導入Git,而Bitbucket支援導入Git,CodePlex,Google Code,HG,SourceForge和SVN。
  • 關于免費計劃:雖然三家服務商都提供免費計劃,但是還是有一些差異。GitHub的Free Plans允許托管無線的公有代碼倉庫,随時進行clone,fork和contribute,對磁盤使用沒有限制,但是項目不能超過1GB和單個檔案不能超過100MB;Bitbucket的Small team plan允許5個成員加入,公有/私有倉庫軍免費,當項目快到達1GB時會有郵件通知;GitLab的cloud-hosted plan允許無限數量的使用者在無限數量的公共和私有項目上進行協作,并且沒有存儲庫有10GB的空間限制。

調研持續內建/部署工具

Gitlab CI

  • 這裡使用 oo-2020-pre3task1 的内容,首先在本地用 maven 重新建立項目,再進行簡單的JUnit4測試:
軟工——淺談“建構之法”
  • 配置Gitlab CI,并進行線上測試和運作(相關Gitlab倉庫在這裡):
軟工——淺談“建構之法”
  • 可以在Jobs的status裡面看到持續內建所有指令輸出的結果:
軟工——淺談“建構之法”

GitHub Actions

  • 這裡使用的檔案與 Gitlab 相同,但是需要将 .gitlab-ci.yml 替換成 .github/workflows/.yml

    (具體代碼倉庫在這裡)

軟工——淺談“建構之法”
  • 根據文檔編寫 yml 檔案,觸發action編譯運作:
軟工——淺談“建構之法”
  • 點開 jobs 可以看到每步執行情況:
軟工——淺談“建構之法”

關于對CI /CD 工具使用後的看法

首先 CI / CD 是包括持續內建(Continuous Integration)、持續傳遞(Continuous Delivery)和持續部署(Continuous Deployment)的新方法。持續內建的重點是将各個開發人員的工作集合到一個代碼倉庫中,主要目的是盡早發現內建錯誤;持續傳遞的目的是最小化部署或釋放過程中固有的摩擦;持續部署是一種更高程度的自動化,無論何時對代碼進行重大更改,都會自動進行建構/部署。這些階段中的每一個都是傳遞管道的一部分 。

我所使用的CI和CD工具的特點特性描述:

  • Gitlab CI 的觸發為 Git 送出檢索 .gitlab-ci.yaml 檔案觸發,其免去了第三方 CI 伺服器對利用 webhook 定時請求 Gitlab 的壓力。本身設計為 Config as Code 将CI / CD 配置托管在項目中,避免每個人手工配置的 CI 或還有不一緻帶來的問題。真正的架構為 C/S 架構模式,可方面的進行橫向擴充,運作 job 性能上不會有影響。其CI過程利用gitlab自帶的郵件通知,不用額外配置通知。
  • Github Action 是Github官方推出的一款 CI 工具。由于 CI 由很多操作組成,比如抓取代碼、運作測試、登入遠端伺服器、釋出到第三方服務等等,Github把這些操作成為 actions。GitHub 允許開發者把每個操作寫成獨立的腳本檔案,存放到代碼倉庫,使得其他開發者可以引用。如果我需要某個 action,不必自己寫複雜的腳本,直接引用他人寫好的 action 即可,整個持續內建過程,就變成了一個 actions 的組合。這就是 GitHub Actions 最特别的地方。GitHub 做了一個官方市場,可以搜尋到他人送出的 actions。
  • 關于 Gitlab CI 與 Github Action 的詳細差別參考該網址,以下列出了幾個個人認為對使用體驗影響較大的方面:
    比較方面 Github Action
    Marketplace NO YES
    Support for CD-Built in and not third party
    CI/CD fully integrated - no 3rd party Plugins/tools need
    Auto CI/CD Pipeline Configuration
  • 就個人目前的使用體驗而言,兩種持續內建工具界面都比較直覺,但Github Action可以自動生成 yml 檔案模闆或者在 marketplace 中找到他人的 Actions ,大大節省了開發者的時間,并且Github上開源項目的優勢也是極其明顯的。