精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

依賴注入與控制反轉:優化Go語言REST API客戶端

開發 前端
在這篇文章中,我展示了如何以及為什么在Go中使用DI和IoC。正確使用DI/IoC可以導致更易于測試和維護的代碼,特別是在代碼庫不斷增長時。雖然代碼示例是用Go編寫的,但這里描述的原則同樣適用于其他編程語言。

在這篇文章中,我將探討依賴注入(DI)和控制反轉(IoC)是什么,以及它們的重要性。作為示例,我將使用Monibot的REST API客戶端。讓我們開始吧:

一個簡單的客戶端實現

我們從一個簡單的客戶端實現開始,允許調用者訪問Monibot的REST API,具體來說,是為了發送指標值。客戶端的實現可能如下所示:

package monibot

type Client struct {
}

func NewClient() *Client {
    return &Client{}
}

func (c *Client) PostMetricValue(value int) {
    body := fmt.Sprintf("value=%d", value)
    http.Post("https://monibot.io/api/metric", []byte(body))
}

這里有一個客戶端,提供了PostMetricValue方法,該方法用于將指標值上傳到Monibot。我們的庫的用戶可能像這樣使用它:

import "monibot"

func main() {
    // 初始化API客戶端
    client := monibot.NewClient()
    // 發送指標值
    client.PostMetricValue(42)
}

依賴注入

現在假設我們想對客戶端進行單元測試。當所有HTTP發送代碼都是硬編碼的時候,我們如何測試客戶端呢?對于每次測試運行,我們都需要一個“真實”的HTTP服務器來回答我們發送給它的所有請求。不可取!我們可以做得更好:讓我們將HTTP處理作為“依賴”;讓我們發明一個 Transport 接口:

package monibot

// Transport傳輸請求。
type Transport interface {
    Post(url string, body []byte)
}

讓我們再發明一個具體的使用HTTP作為通信協議的Transport:

package monibot

// HTTPTransport是一個使用HTTP協議傳輸請求的Transport。
type HTTPTransport struct {
}

func (t HTTPTransport) Post(url string, data []byte) {
    http.Post(url, data)
}

然后讓我們重寫客戶端,使其“依賴”于一個Transport 接口:

package monibot

type Client struct {
    transport Transport
}

func NewClient(transport Transport) *Client {
    return &Client{transport}
}

func (c *Client) PostMetricValue(value int) {
    body := fmt.Sprintf("value=%d", value)
    c.transport.Post("https://monibot.io/api/metric", []byte(body))
}

現在,客戶端將請求轉發到它的Transport依賴。當創建客戶端時,transport(客戶端的依賴項)被“注入”到客戶端中。調用者可以這樣初始化一個客戶端:

import "monibot"

func main() {
    // 初始化API客戶端
    var transport monibot.HTTPTransport
    client := monibot.NewClient(transport)
    // 發送指標值
    client.PostMetricValue(42)
}

單元測試

現在我們可以編寫一個使用“偽造”Transport的單元測試:

// TestPostMetricValue確保客戶端向REST API發送正確的POST請求。
func TestPostMetricValue(t *testing.T) {
    transport := &fakeTransport{}
    client := NewClient(transport)
    client.PostMetricValue(42)
    if len(transport.calls) != 1 {
        t.Fatal("期望1次傳輸調用,但是是%d次", len(transport.calls))
    }
    if transport.calls[0] != "POST https://monibot.io/api/metric, body=\\"value=42\\"" {
        t.Fatal("錯誤的傳輸調用 %q", transport.calls[0])
    }
}

// 偽造的Transport是單元測試中使用的Transport。
type fakeTransport struct {
    calls []string
}

func (f *fakeTransport) Post(url string, body []byte) {
    f.calls = append(f.calls, fmt.Sprintf("POST %v, body=%q", url, string(body)))
}

添加更多的Transport函數

現在假設我們庫的其他部分,也使用了Transport功能,需要比POST更多的HTTP方法。對于它們,我們必須擴展我們的Transport接口:

package monibot

// Transport傳輸請求。
type Transport interface {
    Get(url string) []byte     // 添加,因為health-monitor需要
    Post(url string, body []byte)
    Delete(url string)         // 添加,因為resource-monitor需要
}

現在我們有一個問題。編譯器抱怨我們的fakeTransport不再滿足Transport接口。所以讓我們通過添加缺失的函數來解決它:

// 偽造的Transport是單元測試中使用的Transport。
type fakeTransport struct {
    calls []string
}

func (f *fakeTransport) Get(url string) []byte {
    panic("不使用")
}

func (f *fakeTransport) Post(url string, body []byte) {
    f.calls = append(f.calls, fmt.Sprintf("POST %v, body=%q", url, string(body)))
}

func (f *fakeTransport) Delete(url string) {
    panic("不使用")
}

我們做了什么?由于在單元測試中我們不需要新的Get()和Delete()函數,如果它們被調用,我們就拋出異常。這里有一個問題:每次在Transport中添加新函數時,我們都會破壞現有的fakeTransport實現。對于大型代碼庫來說,這將導致維護噩夢。我們能做得更好嗎?

控制反轉

問題在于我們的客戶端(和相應的單元測試)依賴于一個它們不能控制的類型。在這種情況下,它是Transport接口。為了解決這個問題,讓我們通過引入一個未導出的接口,該接口僅聲明了我們的客戶端所需的內容,來反轉控制:

package monibot

// clientTransport傳輸Client的請求。
type clientTransport interface {
    Post(url string, body []byte)
}

type Client struct {
    transport clientTransport
}

func NewClient(transport clientTransport) *Client {
    return &Client{transport}
}

func (c *Client) PostMetricValue(value int) {
    body := fmt.Sprintf("value=%d", value)
    c.transport.Post("https://monibot.io/api/metric", []byte(body))
}

現在讓我們將我們的單元測試更改為使用假的clientTransport:

// TestPostMetricValue確保客戶端向REST API發送正確的POST請求。
func TestPostMetricValue(t *testing.T) {
    transport := &fakeTransport{}
    client := NewClient(transport)
    client.PostMetricValue(42)
    if len(f.calls) != 1 {
        t.Fatal("期望1次傳輸調用,但是是%d次", len(f.calls))
    }
    if f.calls[0] != "POST https://monibot.io/api/metric, body=\\"value=42\\"" {
        t.Fatal("錯誤的傳輸調用 %q", f.calls[0])
    }
}

// 偽造的Transport是在單元測試中使用的clientTransport。
type fakeTransport struct {
    calls []string
}

func (f *fakeTransport) Post(url string, body []byte) {
    f.calls = append(f.calls, fmt.Sprintf("POST %v, body=%q", url, string(body)))
}

由于Go的隱式接口實現(如果愿意,可以稱之為'鴨子類型'),我們庫的用戶什么也不需要改變:

import "monibot"

func main() {
    // 初始化API客戶端
    var transport monibot.HTTPTransport
    client := monibot.NewClient(transport)
    // 發送指標值
    client.PostMetricValue(42)
}

重新審視Transport

如果我們使IoC成為規范(正如我們應該做的那樣),就不再需要導出Transport接口了。為什么呢?因為如果消費者需要一個接口,讓他們在自己的作用域中定義它,就像我們對'clientTransport'做的那樣。

不要導出接口。導出具體實現。如果消費者需要接口,讓他們在自己的作用域中定義。

總結

在這篇文章中,我展示了如何以及為什么在Go中使用DI和IoC。正確使用DI/IoC可以導致更易于測試和維護的代碼,特別是在代碼庫不斷增長時。雖然代碼示例是用Go編寫的,但這里描述的原則同樣適用于其他編程語言。

責任編輯:武曉燕 來源: 愛發白日夢的后端
相關推薦

2022-04-30 08:50:11

控制反轉Spring依賴注入

2019-09-18 18:12:57

前端javascriptvue.js

2014-01-07 14:39:26

Android開發RxJavaREST

2009-06-12 19:18:08

REST客戶端框架JavaScript

2024-04-01 00:02:56

Go語言代碼

2024-05-27 00:13:27

Go語言框架

2024-07-30 08:12:04

Java消息go

2010-05-31 10:11:32

瘦客戶端

2020-07-14 14:59:00

控制反轉依賴注入容器

2020-11-16 08:05:26

API調用VS Code

2018-12-27 13:11:04

愛奇藝APP優化

2024-04-18 08:39:57

依賴注入控制反轉WPF

2022-09-30 15:31:21

Golang開發工具

2012-12-07 10:15:53

IBMdW

2021-05-07 15:28:03

Kafka客戶端Sarama

2021-10-18 05:00:38

語言GoRequestHTTP

2010-08-31 16:29:40

DHCP客戶端

2011-08-17 10:10:59

2010-12-17 10:16:33

OpenVAS

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端
點贊
收藏

51CTO技術棧公眾號

欧美日韩美女视频| 国产精品永久| 日韩你懂的电影在线观看| 国产制服91一区二区三区制服| 成人黄色免费视频| 久久精品男女| 久久夜色精品亚洲噜噜国产mv| 三大队在线观看| 久久uomeier| 亚洲免费观看高清在线观看| 久久亚洲综合网| 亚洲天堂avav| 国产亚洲激情| 久久精品99久久久久久久久| 一起草在线视频| 日韩福利影视| 色综合色狠狠天天综合色| 老司机av福利| 久色视频在线| 粉嫩嫩av羞羞动漫久久久| 国产精品igao视频| 精品人妻在线播放| 久久免费精品视频在这里| 精品日韩99亚洲| 天天干天天av| 午夜精品成人av| 亚洲国产综合人成综合网站| 亚洲成人第一| 久草在现在线| 91日韩在线专区| 91九色对白| 亚洲中文字幕在线一区| 亚洲永久免费| 97精品伊人久久久大香线蕉| 国产尤物在线播放| 欧美丰满日韩| 这里精品视频免费| 欧美成人国产精品一区二区| 日韩极品少妇| 亚洲国产欧美一区二区丝袜黑人| 天天色天天综合网| 激情中国色综合| 日本韩国欧美三级| www.亚洲天堂网| 韩日毛片在线观看| 污片在线观看一区二区| 国产美女主播在线| 国产探花视频在线观看| 亚洲最快最全在线视频| 亚洲精品国产精品久久| 春暖花开成人亚洲区| 久久先锋资源网| 免费国产一区二区| 欧洲毛片在线| 91看片淫黄大片一级在线观看| 精品乱码一区| 日本免费不卡| 久久久久久久久久久99999| 欧美亚洲免费在线| 精品美女视频在线观看免费软件| 久久久精品日韩欧美| 欧美精品久久久| 都市激情一区| 国产精品国产三级国产aⅴ原创 | 国产成人精品一区二区色戒| 老司机亚洲精品| 国产精品美女久久久免费| 看黄色一级大片| 免费不卡在线观看| 国产日韩精品综合网站| aaa国产视频| 丰满白嫩尤物一区二区| 久久久亚洲综合网站| 国产原创av在线| 国产精品麻豆网站| 400部精品国偷自产在线观看| 1区2区3区在线视频| 亚洲va中文字幕| 久章草在线视频| 久久er热在这里只有精品66| 91 com成人网| 精品一区二区三区四区五区六区| 一区二区美女| 中文字幕精品在线| 欧美三级小视频| 日韩视频免费| 国产精品美女无圣光视频| 一区二区三区精| 成人免费av网站| 日本一区二区三区在线视频 | 国产三级欧美三级| 亚洲欧美影院| 成人免费高清观看| 欧美中文字幕一区| 国产吃瓜黑料一区二区| 国产探花一区在线观看| 久久影院模特热| 国产剧情在线视频| 国产精品一区二区久激情瑜伽 | 国产区精品区| 欧美国产在线视频| 亚洲高清视频免费观看| 国产成人免费网站| 日韩欧美视频一区二区| 92国产精品| 欧美午夜免费电影| 在线播放第一页| 欧洲美女日日| 欧美国产日韩精品| 少妇无套内谢久久久久| 成人黄色一级视频| 伊人色综合影院| 惠美惠精品网| 亚洲电影天堂av| 三级av在线免费观看| 国产精品一二| 大波视频国产精品久久| 天堂中文8资源在线8| 欧美性猛交xxxx乱大交| 久久黄色一级视频| 欧美激情偷拍自拍| 国产精品1234| 天堂在线资源网| 色欧美自拍视频| 久久噜噜噜精品国产亚洲综合 | 色狠狠一区二区| 久久久久中文字幕亚洲精品| 久久中文视频| 国产精品美女在线| 国内在线精品| 狠狠躁夜夜躁久久躁别揉| 午夜性福利视频| 中文在线日韩| 成人自拍性视频| 视频一区二区三区不卡 | 国产精品污视频| 国产丝袜美腿一区二区三区| 日韩在线视频在线观看| 加勒比久久高清| 欧美激情在线观看| 亚洲a视频在线| 亚洲男同性恋视频| 在线观看日本www| 欧美国产一级| 成人激情视频在线播放| 亚洲欧美视频一区二区| 欧美区在线观看| www成人啪啪18软件| 日本午夜精品一区二区三区电影| 日韩成人av电影在线| 性欧美1819sex性高清| 亚洲欧美成人精品| 精产国品一区二区| 国产日韩视频一区二区三区| 成人黄色一区二区| 天天躁日日躁成人字幕aⅴ| 性金发美女69hd大尺寸| 少妇人妻偷人精品一区二区| 亚洲午夜精品在线| 日韩www视频| 国产精品一区毛片| 日韩av电影免费在线| 国产成人精品一区二区三区在线| 日韩视频在线免费观看| 国产精品日韩无码| 亚洲成人免费视频| 亚洲av片不卡无码久久| 美洲天堂一区二卡三卡四卡视频| 影音先锋欧美资源| 欧美久久亚洲| 国产69精品久久久久久| 日色在线视频| 欧美日韩国产一级二级| 欧美日韩偷拍视频| 99久久婷婷国产综合精品 | 国产精品综合在线视频| 国产欧美久久久久| 啪啪亚洲精品| 91色精品视频在线| 国产极品人妖在线观看| 亚洲色图欧美制服丝袜另类第一页| 国产一级片一区二区| 亚洲三级在线免费| 国产 xxxx| 免费成人在线影院| 国产传媒久久久| 久久99性xxx老妇胖精品| 国产欧美精品在线播放| av免费不卡| 色伦专区97中文字幕| www.热久久| 欧美在线你懂的| 久久中文字幕无码| 欧美国产日韩精品免费观看| 免费看的av网站| 久久字幕精品一区| 免费的一级黄色片| 北条麻妃国产九九九精品小说| 1卡2卡3卡精品视频| 芒果视频成人app| 欧美精品少妇videofree| 激情小视频在线| 日韩欧美成人午夜| 国产美女www爽爽爽| 亚洲综合另类小说| 国产aaaaaaaaa| 99国产精品久久久久| 一级淫片在线观看| 日韩精品每日更新| 男人日女人逼逼| 午夜免费一区| 日韩欧美亚洲在线| 欧美三级午夜理伦三级小说| 亚洲一区久久久| 国产精品久久久久久吹潮| 69久久夜色精品国产7777| gogo在线观看| 视频在线观看一区二区| 青青青免费视频在线2| 精品国产一区二区三区忘忧草| 亚洲一区二区激情| 在线观看区一区二| 精品欧美一区二区三区免费观看| 一区二区高清视频在线观看| 婷婷伊人五月天| 成人免费在线视频| 极品蜜桃臀肥臀-x88av| 久久久亚洲欧洲日产国码αv| jjzz黄色片| 国产成人在线视频播放| 午夜啪啪小视频| 久久99精品久久久久久国产越南| 国产成人久久777777| 国产精品日韩久久久| 免费av手机在线观看| 亚洲特级毛片| a级免费在线观看| 好吊日精品视频| 国产免费一区二区视频| 欧美二区不卡| 国产911在线观看| 欧美精品一卡| 国产美女作爱全过程免费视频| 伊人久久大香线蕉综合四虎小说| 亚洲一区二区三区免费观看| 亚洲四虎影院| 欧美一区第一页| 欧美xxx视频| 国产suv精品一区二区| 美女18一级毛片一品久道久久综合| 91高潮在线观看| 欧美日韩123区| 国产激情999| 少妇精品视频在线观看| 成人综合国产精品| 国产精品久久免费视频| 91天堂在线观看| 91精品啪在线观看国产手机 | www.午夜激情| 亚洲第一视频网| 性感美女视频一二三| 日本韩国欧美一区二区三区| 亚洲国产精品无码久久久| 在线观看国产91| 国产精品人人爽| 亚洲成人精品久久| 黄色大片在线看| 日日狠狠久久偷偷四色综合免费| av电影高清在线观看| 欧美激情在线视频二区| 日本久久免费| 成人精品视频99在线观看免费 | 精品欧美一区二区在线观看视频| 欧美一级一片| 日韩一区不卡| 一本一道久久综合狠狠老| 久久亚洲精品无码va白人极品| 在线精品观看| 成人午夜激情av| 国产精品一区二区久久精品爱涩| av2014天堂网| 国产精品天天看| 精品无码久久久久| 色欧美日韩亚洲| 国产男男gay网站| 亚洲精品白浆高清久久久久久| 国产高清视频在线播放| 久久综合免费视频| 在线手机中文字幕| 成人国产精品久久久| 欧美人体视频| 爱爱爱视频网站| 国产精品美女久久久| 日韩av自拍偷拍| 久久久久久久久99精品| 欧美黄色一级网站| 在线日韩一区二区| 蜜臀av中文字幕| www.精品av.com| 在线视频超级| 国产精品高清一区二区三区| 红桃成人av在线播放| 蜜臀av色欲a片无码精品一区| 美女精品自拍一二三四| yy1111111| 亚洲精品网站在线观看| 精品乱码一区内射人妻无码| 亚洲第一av网| 欧美激情视频在线播放| 欧美一级片久久久久久久| 日本超碰一区二区| 亚洲午夜激情| 久久裸体视频| 亚洲天堂美女视频| 亚洲免费av在线| 曰批又黄又爽免费视频| 亚洲图中文字幕| 欧美aa在线观看| 国产精品日韩一区二区| 91精品国产91久久久久久密臀| 久久精品视频91| 97久久超碰国产精品电影| 欧美黄色一级网站| 欧美一级xxx| 免费av在线网址| 国产精品入口夜色视频大尺度 | 午夜精品免费观看| 亚洲精品久久久久国产| 精品精品导航| 亚洲91精品在线观看| 精品视频91| 中文字幕第一页亚洲| 秋霞电影网一区二区| 亚洲性猛交xxxx乱大交| 欧美性xxxx在线播放| 天天操天天射天天| 久久免费国产精品1| y111111国产精品久久久| 日韩不卡视频一区二区| 国产美女精品一区二区三区| 色老板免费视频| 7777精品伊人久久久大香线蕉完整版| 91亚洲精选| 国产精品最新在线观看| 91影院成人| aaaaaaaa毛片| 亚洲精品自拍动漫在线| 精品久久国产视频| 欧美大片在线影院| 6080成人| 成人中文字幕在线播放| 91婷婷韩国欧美一区二区| 日本视频免费观看| 丝袜亚洲欧美日韩综合| 香蕉久久一区| 日韩免费在线观看av| av激情综合网| 91视频久久久| 中文字幕亚洲自拍| 国产电影一区| 美女扒开大腿让男人桶| 91在线观看地址| 午夜精品久久久久久久蜜桃| 在线色欧美三级视频| 粉嫩av国产一区二区三区| 久久久国内精品| 91在线观看免费视频| 中文字幕免费观看视频| 久久伊人91精品综合网站| 久久99国产精品久久99大师 | 亚洲日本无吗高清不卡| 国内精品自线一区二区三区视频| 国产十六处破外女视频| 亚洲精品99久久久久| 欧美三级精品| 成人午夜免费剧场| av激情亚洲男人天堂| 中文天堂在线资源| 欧美国产日本高清在线| 伊人久久大香线蕉综合网站| 超碰人人草人人| 午夜电影久久久| 自拍视频在线网| 古典武侠综合av第一页| 日韩国产在线观看| 久草视频在线免费看| 日韩精品在线影院| 亚洲精品伦理| www.99热这里只有精品| 国产精品免费久久久久| 黄色福利在线观看| 国产精品高清免费在线观看| 欧美在线二区| 在线不卡av电影| 日韩精品一区二区三区视频播放 | 动漫性做爰视频| 亚洲女人被黑人巨大进入| 青草伊人久久| 中文字幕网av| 狠狠躁夜夜躁久久躁别揉|