1. 程式人生 > >關於使用第三方庫、程式碼複用的一些思考

關於使用第三方庫、程式碼複用的一些思考

不管是不要重複造輪子,還是站在巨人的肩膀上,對於軟體開發來說,程式碼複用都是最基本的原則之一。

程式碼複用,可能是DIY(dont repeat yourself),也可能是使用別人的程式碼,或者是開源專案,或者是其他團隊提供的元件、服務,或者是團隊內他人實現的公共模組,這些複用大大減少了專案的開發週期和成本。

但怎樣才算是高效、正確的第三方程式碼使用姿勢呢?在實操中,也會出現一些使用第三方程式碼導致失控的情況,比如使用用了一些第三方程式碼,但年久失修,當線上事故貌似與第三方程式碼有關時,無法快速定位、解決問題。

本文是閱讀《clean code》的第八章邊界(Boundaries)時的一些思考。

本文地址:https://www.cnblogs.com/xybaby/p/11372846.html

本文將複用的程式碼分為兩類:

  • 一類是團隊外的程式碼,具體指第三方庫、開源庫、公司內其他團隊的通用元件,其特徵是,這樣的程式碼往往需要做的比較通用,大而全;專案團隊只是使用者,很難從根本上影響其設計或實現。
  • 另一類則是團隊內的程式碼,即專案團隊成員自行封裝的一些通用模組、通用元件,其特徵是核心為專案服務,比較方便協商修改。

如何複用第三方庫程式碼

這裡的複用,不侷限於程式碼,也包括可供遠端呼叫的服務。一般來說,專案會調研、選擇一些開原始碼,也會使用公司內基礎服務部門或者雲端計算上的一些服務,我覺得這都算複用。

最小化、集中化程式碼複用

第三方庫往往追求功能(服務)的普適性,這樣程式碼就能在多個環境中工作,吸引更多的使用者。而使用者往往只需要滿足特定需求的部分介面,對於不需要的功能(以及不建議的使用方式),對專案來說反而是負擔,控制不當反而會帶來風險。

比如redis,既能做記憶體資料庫,也能持久化;既支援單點部署,也能通過sentinel、cluster提供高可用以及水平擴充套件;而且還支援pub-sub(以及比較新的stream)。但在我們的專案中,只用來記憶體快取,而且對可用性、伸縮性也沒有太大需求。

原則上,使用第三方庫時,使用到的介面(服務)越少越好,將其封裝到單獨的檔案(類、模組),在其他地方不能直接使用第三方庫。通過適配,只將需要的部分功能納入,不需要的功能(介面)不要暴露出來。

這樣的好處在於入口統一,將所有對第三方庫的使用集中到最少量的程式碼裡面,便於維護。同時,這也是分層的思想,將業務程式碼與第三方庫解耦合,便於替換實現。

learning tests

要將一個開源專案引入自己的業務程式碼,需要進行科學的調研和完備的測試。調研包括但不限於:與業務需求的重合度,開源社群的成熟度、活躍度等。而測試應包含以下幾個方面

  • 功能測試
  • 效能測試
  • 壓力測試
  • 故障測試

前兩項是最基礎的測試,主要判斷是第三方庫是否符合業務的功能、效能要求,同時掌握正確的使用姿勢。而後兩者,則常常是第三方庫以單獨的服務部署執行時的測試要點。

為了進行測試,我們會有一些測試程式碼,也許會參考專案自帶的unittest、 code sample、tutorial、benchmark。但問題在於,這樣的測試程式碼經常用完就扔,這樣導致

  • 如果後面出現問題,我們就需要不斷除錯,來確定是類庫本身的問題,還是我們使用姿勢的問題。
  • 當地三方庫升級之後,應用不敢跟著升級,因為沒有手段保證新版本的類庫提供了同等契約。

第二個問題我想很多很多人都會遇到,當依賴的第三方庫升級的時候,專案是否跟著一起升級你?兩種比較極端的策略我都遇到過,一種是始終更新到第三方庫的最新穩定版本;另一種是基本不升級,自己維護某個特定版本。

learning test能解決上述的第二個問題:

我們將所有的測試整理為一整套針對所使用的功能的單元測試,這些測試覆蓋了我們對功能、效能、穩定性都諸多方面的需求。當第三方類庫的版本更新的時候,我們只要把單元測試再跑一遍,就可以判斷新程式碼的程式碼是否提供了同等的契約,也就可以比較安全的進行升級。

不難看到,上一小節,“集中化第三方程式碼使用”是learning test的基礎,讓我們很清楚的知道應該對那些介面進行測試,如果要擴充套件對第三方庫的使用,也能很方便的增加、維護對應的測試。

如何複用團隊內的程式碼

在團隊內,也是非常鼓勵程式碼的複用,比較常見的方式是形成各種通用的元件。那麼,如果程式設計師A使用了程式設計師B提供的公共模組出了問題,那麼責任該如何劃分?

如果是開原始碼,毫無疑問只能責怪使用者,但是在團隊中,似乎並不能完全歸咎於使用者。公共元件的使用者一般並不會對使用進行完整的測試,也會認為,“都是一個團隊的,就應該提供者保證質量,方便快速使用”。

我認為,使用者的責任佔主要,使用者應該就使用方式進行測試,如果提供者已經提供了相應的單元測試,而且能通過,那麼就可以直接使用。否則應該新增對應的測試case,如果無法通過,則可以找提供者協商解決。對於通用模組、通用元件的提供者,也應該有義務提供高覆蓋率的單元測試,一來開發的時候因為本身就會測試,並不會增加額外的工作量;二來是對使用者的一份正式的保證,也能提高自己在團隊的影響力