這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
總結下Go的package設計哲學
- 明確目的
- 在準備設計一個包之前,我們需要明確它的目的。
- 包的命名就必須明確體現其目的,而不僅僅是為了存放代碼。像標準庫的io,http,fmt這些包名就很好,而像util.helper,common這種命名就是反面教材。
- 可用性
- 想想使用這個包的人真正的需求,包的使用一定要直觀、簡單。
- 在不斷反覆式開發法、最佳化、完善的時候,不能讓引用這個的程式出錯。
- 防止出現需要類型斷言具體類型的需求。
- 讓單個包的代碼量簡化到最少,減少bug,易於掌控。
- 可移植性
- 始終追求最高可移植性。
- 如果包合理實用,就不要過多在意其它人的意見,沒有適合所有人的完美的包。
- 不要讓包成為單一依賴點(即所有其它包都依賴它),每個包都有自己的設計目的,可能多個包會有重複的類型,即便重複定義也不要讓包成為單一依賴點,這是API設計原則。
項目結構組織的最佳實務
有兩種類型的項目,一種是產生可運行程式的項目(application project),另一種是專門用於被其它項目引用的套件項目(kit project)。
對於套件項目,結構組織根據實際項目用途而定,而對於可運行程式的項目,用這樣的結構:
├── cmd
├── internal
└── vendor
vendor存放依賴包,internal存放本項目內部使用的包,cmd存放可啟動並執行程式的代碼,如果該項目有多個可運行程式,可以在cmd下建子目錄。
注: internal可以被編譯器識別,在internal下面的包是不能被其它項目引用的。
internal下面如果有很多包,並且它們需要用到一些相同的邏輯,比如加解密、網路請求等,可以在internal中建platform目錄,存放內部使用的套件包,這樣的結構:
├── cmd
├── internal
│ └── platform
└── vendor
註:platform下面的包如果成熟了,在未來它們你可以將其開源變成公有的套件項目,供別人的項目引用。
關於日誌輸出,公有的套件項目不要列印日誌,因為它是要被其它項目引用的,列印日誌的邏輯應該讓可啟動並執行項目自己來決定。
附上相關演講視頻:《Go語言面向包設計》
插播廣告,go的http請求庫req,讓http請求簡單到極致:https://github.com/imroc/req