您好,登錄后才能下訂單哦!
本篇內容介紹了“Go包內的組成是怎樣的”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在開發微服務時,按組件拆分服務很有用。每個組件都應該是獨立的,理論上,如果需要,可以將其提取到外部服務。如何理解和實現呢?
假設我們有一個服務,它處理與訂單相關的所有事情,比如發送電子郵件的確認、將信息保存到數據庫、連接到支付提供商等。每個包都應該有一個名稱,該名稱清楚地說明了它的用途,并且遵守命名標準。
這只是我們有 3 個包的項目的一個例子:confemails,payproviders和warehouse。包名應盡量簡短并能讓人一目了然。
每個包都有自己的 Setup()函數。該函數只接收能讓該包運行的最基本的參數。例如,如果包對外提供 HTTP 服務,那么 Setup() 函數則僅需要接受一個類似 mux route 的 HTTP route。當包需要訪問數據庫時,Setup() 函數也是只接受 sql.DB 參數就可以了。當然,這個包也可能需要依賴另一個包。
知道了模塊的外部依賴,下一步我們就可以專注于如何在模塊內組織代碼(包括相關依賴的處理)。在最開始,這個包包含以下文件: setup.go - 其中包含 Setup()函數, service.go - 它是邏輯文件, repository.go - 它是在讀取/保存數據到數據的的文件。
Setup()函數負責構建模塊的每個構建塊,即服務、存儲庫、注冊事件處理程序或 HTTP 處理程序等等。這是使用這種方法的實際生產代碼的一個例子。
func Setup(router *mux.Router, httpClient httpGetter, auth jwtmiddleware.Authorization, logger logger) {
h := httpHandler{
logger: logger,
requestClaims: jwtutil.NewHTTPRequestClaims(client),
service: service{client: httpClient},
}
auth.CreateRoute("/v1/lastAnswerTime", h.proxyRequest, http.MethodGet)
}
以上代碼中,它構建了 JWT 中間件,這是一個處理所有業務邏輯(以及日志的位置)并注冊 HTTP 處理程序的服務。正因為如此,模塊是非常獨立的,并且(理論上)可以轉移到單獨的微服務中,而不需要做太多工作。最后,所有的包都在 main 函數中配置。
有時,我們需要一些處理程序或數據庫驅動。例如,一些信息可以被存儲在數據庫中,然后通過事件發送到平臺的不同部分。使用像 saveToDb()這樣的方法將數據只保存在同一個庫中是很不方便的。所有類似的元素都應該由以下功能分割:repository_order.go 或 service_user.go。如果對象的類型超過 3 種,則將其移動到單獨的子文件夾中。
說到測試,我堅持一些原則。首先,在 Setup()函數中使用接口。這些接口應該盡可能小。在上面的例子中,有一個 httpGetter 接口。接口中只有Get()函數。
type httpGetter interface {
Get(url string) (resp *http.Response, err error)
}
謝天謝地,我只需要模擬一個方法。接口的定義需要盡可能地接近它的用途。
其次,嘗試編寫更少的測試用例的同時可以覆蓋到更多的代碼。對于每個主函數的決策/操作,一個成功的測試用例和一個失敗的測試用例應該足夠覆蓋大約 80% 的代碼。有時,程序中有一些關鍵部分,這部分可以被單獨的測試用例覆蓋。
最后,在以 _test
為后綴的單獨包中編寫測試,并將其放入模塊中。把所有的東西都放在一個地方是很有用的。
當您想要測試整個應用程序時,請在主函數旁邊的setup()函數中準備好每個依賴項。它將為生產環境和測試環境提供相同的設置,可以為您避免一些 bug。測試應該重用 setup()函數,并且只模擬那些不易模擬的依賴項(比如外部 api)。
“Go包內的組成是怎樣的”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。