go語(yǔ)言實(shí)現(xiàn)依賴注入的示例代碼
依賴注入(Dependency injection)
依賴注入和控制反轉(zhuǎn)恰恰相反,它是一種具體的編碼技巧。我們不通過 new 的方式在類內(nèi)部創(chuàng)建依賴類的對(duì)象,而是將依賴的類對(duì)象在外部創(chuàng)建好之后,通過構(gòu)造函數(shù)、函數(shù)參數(shù)等方式傳遞(或注入)給類來使用。
DI(依賴性注入)是一種技術(shù),當(dāng)你的模塊間接地接受依賴性。他們不知道依賴的實(shí)現(xiàn),只知道接口。
我們?yōu)槭裁葱枰?/h2>
DI 可以幫助我們編寫低耦合的代碼。這意味著你將能夠隨時(shí)交換你的代碼,并有助于重用它們的一些部分。
在寫單元測(cè)試時(shí),使用 mock 方式注入是一個(gè)非常好的實(shí)踐。
參考代碼
我們有一個(gè)小小的項(xiàng)目:main.go 和 兩個(gè)服務(wù)–日志和緩存
├───cmd
│ └───main.go
└───services
├───logger
│ └───logger.go
└───cache
└───cache.go
它們是如何工作的?我們有一個(gè)緩存服務(wù),如果你想把一些東西存儲(chǔ)在像Redis這樣的快速存儲(chǔ)中,就可以使用它。
// cache.go
import (
"fmt"
"sync"
)
// 將被注入的記錄器服務(wù)的接口,用小寫的方式來隱藏出口,是一個(gè)好的方式。
type logger interface {
Error(error)
Info(string)
}
type Cache struct {
logger logger
m *sync.Map
}
// NewCache 我們服務(wù)的構(gòu)造函數(shù),接收將被注入的服務(wù)的接口(我們可以注入幾個(gè)服務(wù)),并返回結(jié)構(gòu)(緩存的實(shí)例)。
func NewCache(logger logger) *Cache {
return &Cache{
logger: logger,
m: new(sync.Map),
}
}
func (r *Cache) Get(key string) (string, error) {
rawValue, ok := r.m.Load(key)
if !ok {
err := fmt.Errorf("not found: %s", key)
r.logger.Error(err)
return "", err
}
return rawValue.(string), nil
}
func (r *Cache) Set(key string, data []byte) {
r.m.Store(key, data)
r.logger.Info(fmt.Sprintf("store key: %s", key))
}
日志服務(wù)用來對(duì)日志的持久化存儲(chǔ)以及分析
// logger.go
import "fmt"
type sentryClient interface {
sendMessage(interface{})
}
type NormalSentryClient struct{}
func (s *NormalSentryClient) sendMessage(i interface{}) {
fmt.Printf("send message %+v to sentry\n", i)
}
type Logger struct {
sentry sentryClient
}
func NewLogger(sentryClient sentryClient) *Logger {
return &Logger{
sentry: sentryClient,
}
}
// 我們看到這里有四個(gè)方法,但是 cache 對(duì)象只能看到兩個(gè):Error 以及 Info
func (l *Logger) Error(e error) {
fmt.Printf("[ERROR] %+v\n", e)
}
func (l *Logger) Info(msg string) {
fmt.Printf("[INFO] %s\n", msg)
}
func (l *Logger) Debug(msg string) {
fmt.Printf("[DEBUG] %s\n", msg)
}
func (l *Logger) Log(msg string) {
fmt.Printf("[LOG] %s\n", msg)
}
// main.go
func main() {
// 注冊(cè)服務(wù)
sentryService := new(logger.NormalSentryClient)
loggerService := logger.NewLogger(sentryService)
cacheService := cache.NewCache(loggerService)
cacheService.Set("test", []byte("test"))
cacheService.Get("test1")
}
輸出:
[INFO] store key: test
[ERROR] not found: test1
golang DI 開源庫(kù)
- inject:基于反射,運(yùn)行時(shí)注入。但是已經(jīng)不維護(hù)了。
- wire:AST,編譯期注入。
- dig,F(xiàn)x:基于反射,運(yùn)行時(shí)注入。
以上就是go語(yǔ)言實(shí)現(xiàn)依賴注入的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于go實(shí)現(xiàn)依賴注入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在Mac中搭建go語(yǔ)言開發(fā)環(huán)境的操作步驟
go語(yǔ)言在開發(fā)效率和運(yùn)行效率中的優(yōu)勢(shì)讓很多人青睞,所以有傾向打算轉(zhuǎn)向go語(yǔ)言的開發(fā)。下面介紹在Mac中g(shù)olang的開發(fā)環(huán)境配置。有需要的可以參考借鑒。2016-08-08
golang實(shí)現(xiàn)圖像驗(yàn)證碼的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用golang實(shí)現(xiàn)簡(jiǎn)單的圖像驗(yàn)證碼,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
golang并發(fā)工具M(jìn)apReduce降低服務(wù)響應(yīng)時(shí)間
這篇文章主要為大家介紹了golang并發(fā)使用MapReduce降低服務(wù)響應(yīng)時(shí)間實(shí)踐使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
go語(yǔ)言實(shí)現(xiàn)sftp包上傳文件和文件夾到遠(yuǎn)程服務(wù)器操作
這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)sftp包上傳文件和文件夾到遠(yuǎn)程服務(wù)器操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12
Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之希爾排序示例詳解
這篇文章主要為大家介紹了Go語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之希爾排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Golang實(shí)現(xiàn)單元測(cè)試中的接口層
接口層主要負(fù)責(zé)的就是請(qǐng)求的處理,最常見的就是?HTTP?請(qǐng)求的處理。這篇文章主要為大家介紹了Golang如何實(shí)現(xiàn)單元測(cè)試中的接口層,需要的可以參考一下2023-03-03

