2014-07-05 98 views
2

此刻我有以下內容的包store我應該避免在golang中打包單身人士嗎?

package store 

var (
    db *Database 
) 

func Open(url string) error { 
    // open db connection 
} 

func FindAll(model interface{}) error { 
    // return all entries 
} 

func Close() { 
    // close db connection 
} 

這允許我使用store.FindAll從其他包我在做main.gostore.Open

但是,正如我迄今爲止所看到的,大多數包傾向於提供一個結構,您需要初始化自己。只有少數情況下使用這種全球方法。

這種方法有什麼缺點,我應該避免它?

+0

注意,有些軟件包,如標準庫的'log'包,提供一個全球性的記錄,也全部:如果有人致電Open兩次應該發生什麼你可以構建額外的獨立記錄器。 (包API僅僅是對結構的封裝)。 – LinearZoetrope

回答

3

標準http包具有用於通用usecases和ServerMux又具有ServerMux稱爲DefaultServerMuxhttp://golang.org/pkg/net/http/#pkg-variables)爲方便起見,一個默認實例。因此,當您撥打http.HandleFunc時,它會在默認多路複用器上創建處理程序。您可以在log和許多其他軟件包中找到相同的方法。這基本上是你的「單身」方法。

但是,我認爲在您的用例中遵循該模式並不是一個好主意,因爲無論缺省數據庫如何,用戶都需要調用Open。而且,正因爲如此,使用默認實例就沒有真正的幫助,而是實際上使其不太方便:

d := store.Open(...) 
defer d.Close() 
d.FindAll(...) 

是既寫容易得多,閱讀比:

store.Open(...) 
defer store.Close() 
store.FindAll(...) 

而且,還有一些語義問題:

store.Open(...) 
defer store.Close() 
... 
store.Open(...) 
store.FindAll(...) // Which db is this referring to? 
3
  1. 您無法一次實例化連接到2個存儲。
  2. 使用諸如gomock之類的便利工具,您不能輕易地在依賴代碼的單元測試中嘲笑存儲。
+0

是否有任何的dos-and-dont's for go?我覺得在體系結構方面仍然有些不安全:/ – bodokaiser

+0

全局變量通常很糟糕。這並不具體,並且與架構沒有任何關係。 – Dustin