首页 > 其他分享 >【转】Is there a better dependency injection pattern in golang?

【转】Is there a better dependency injection pattern in golang?

时间:2023-02-06 19:00:53浏览次数:59  
标签:小明 依賴 pattern there share 仲介公司 golang 阿姨 data

 https://coolshell.cn/articles/9949.html

 https://dotblogs.com.tw/daniel/2018/01/17/140435

 

https://github.com/golobby/container

 

https://blog.drewolson.org/dependency-injection-in-go

https://quii.gitbook.io/learn-go-with-tests/go-fundamentals/mocking

 

---------------------

案例解釋:

小明是個愛乾淨的人,但他工作時常加班導致房間雜亂,他不能忍受此狀況,所以小明去找一個清潔阿姨每天幫忙他打掃家裡

 

哪天阿姨哪天有事不能打掃,小明就必須要再去找人來幫忙打掃,由此可知小明耦合阿姨

------------------------------------------------------------------------------------

 

如果今天是....

小明把他要的條件給「打掃仲介公司」,仲介公司幫他尋找有沒有符合小明需求的打掃阿姨,假如今天A阿姨請假了,仲介公司會自動找另一個符合需求B阿姨幫忙打掃...

 

原本小明需耦合於打掃阿姨,現在被「仲介公司」做了控制反轉讓「仲介公司」來提供打掃阿姨。

小明不用管是否今天有人會來打掃,「仲介公司」會幫小明找到一個掃地阿姨。

 

「仲介公司」可看作 依賴注入容器
「小明」可看作 被動接收物件

「打掃阿姨」可看作 被依賴物件

 

在使用IOC容器前需先了解雙方的依賴關係(誰依賴誰?)

 

上述還有一個很重要的觀念是,依賴和被接收對象要倚賴抽象。

 

 

範例使用:VS2015

IOC容器:AutoFac

下面範例來說明上面的例子

 

小明自己依賴於掃地阿姨

依賴程式碼寫在小明類別內部日後要更改只能動內部程式碼。

/// <summary>
/// 小明直接依賴 Aunt 不是依賴抽象
/// 日後要改必須動內部
/// </summary>
public class Mine
{
    public Aunt aunt = new Aunt();

    public void Room()
    {
        aunt.Swapping();
    }
}

 

呼叫使用時

Mine mine = new Mine();
mine.Room();

 

小明找仲介公司
 

仲介公司(Ioc容器)

在仲介公司內註冊需求,讓仲介公司日後幫你找人(註冊的類別)

/// <summary>
/// 仲介公司
/// </summary>
/// <returns></returns>
private static IContainer MiddleCompany()
{
    ContainerBuilder builder = new ContainerBuilder();

    //在仲介公司裡寫需求人申請單
    builder.RegisterType<MineWithMiddle>();
    //小明所需打掃阿姨需求
    builder.RegisterType<Aunt>().As<ISwapable>();

    return builder.Build();
}

 

使用起來

IContainer middleCompany = MiddleCompany();
//仲介公司(IOC AutoFac)自動幫小明注入一個打掃阿姨
MineWithMiddle mineWithMiddle = middleCompany.Resolve<MineWithMiddle>();

mineWithMiddle.Room();

 

總結:

  1. 系統中模組建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。
    像網頁瀏覽器和伺服器是依賴Http協議,用戶端不管是手機.電腦,平板,伺服器端php,asp.net,java都可互相交信,依賴Http協議共用的合約
  2. 控制反轉:是一個設計思想 ,把對於某個物件的控制權移轉給共同第三方
  3. 依賴注入:把被依賴物件注入被動接收物件中


範例原始碼 :https://github.com/isdaniel/IOC_Sample

參考連結 : http://www.cnblogs.com/xdp-gacl/p/4249939.html

----------------------

 

 

 

 

-------

Is there a better dependency injection pattern in golang?

Ask Question Asked 6 years ago Modified 5 months ago Viewed 62k times   50

Given this code:

package main

import (
    "fmt"
)

type datstr string

type Guy interface {
   SomeDumbGuy() string
}

func (d *datstr) SomeDumbGuy() string {
  return "some guy"
}

func someConsumer(g Guy) {
  fmt.Println("Hello, " + g.SomeDumbGuy())
}

func main() {
    var d datstr
    someConsumer(&d)
}

Is the wiring of components together that's done in main the right way to wire a dependency together? It seems like I'm over using this a bit in my code. Is there a common pattern better than this, or am I overthinking it?

Share   asked Jan 27, 2017 at 17:48 Justin Thomas's user avatar Justin Thomas 5,55933 gold badges3838 silver badges6262 bronze badges
  • 4 Bit of an opinion-based question, but that's the style I personally prefer. Unexported struct, exported interface, struct stored by pointer in the interface. Makes mocking and middleware wrapping super easy, and is better aligned to an object-oriented abstraction principle than exported structs. Only addition I might make is a factory function for the datastr type that returns a Guy interface, as this gives a compile-time guarantee that your structure fulfills the interface it is expected to fulfill.  – Kaedys  Jan 27, 2017 at 18:24 
  • 1 quii.gitbook.io/learn-go-with-tests/go-fundamentals/…  – user4466350  Jul 28, 2021 at 17:42      

    The best practice is not to use a DI library. Go is meant to be a simple language that is easy to follow. A DI library/framework will abstract that away from you (and to some extent make DI magical).

    Share   edited Jan 31, 2021 at 11:44 Inanc Gumus's user avatar Inanc Gumus 23.8k99 gold badges8484 silver badges9999 bronze badges answered Feb 17, 2020 at 22:45 Zeeshan's user avatar Zeeshan 1,12911 gold badge99 silver badges1212 bronze badges
    • 6 Unfortunately haven't used wire and neither am i an expert in DI in Golang. However, i strongly believe that no specific pattern is needed since any library would complicate the program flow and Golang aims to be a language which does not have any magic and is easy to follow.  – Zeeshan  Mar 3, 2020 at 4:18
    • 54 If this is classed as the best practice, please add a Go doc reference to that effect. Considering that Google created wire as a DI system that avoids reflection and maintains the calling clarity I find this answer more likely to be incorrect.  – Jeremy  Feb 18, 2021 at 17:36
    • 2 No Go Doc reference; have myself read a bunch of articles and effective go. Using no DI framework is more idiomatic Go compared to using a DI framework that does reflection or magic under the hood.  – Zeeshan  Mar 18, 2021 at 5:40
    • 11 Says who? I've seen quite a few good projects that were using some sort of DI. Also Google with its Wire would argue with your statement...  – Dmytro Titov  Apr 17, 2021 at 23:47
    •   Is only I think this DI thing is squalid (by adding a new function variable?) And that why testing looks like shit) For example, I have a service who do some little logic and send a request to Google Translate API, this service is used by another service, why for the testing parent service need to know all about children service dependencies and insert them into function as params - It confuses me  – fedrbodr  Oct 26, 2021 at 5:57
    • 3 Go allows you to make library that does DI. Abstraction is needed to some degree. Just follow DRY and KISS principle. There is no such thing as best practice to not use XYZ libraries. Unless your team abused it. IMHO.  – rhzs  Jan 1, 2022 at 10:18
    • 2 Anyone coming from an enterprise programming world would not argue that DI should not be used. This is definitely not a best practice, in contrast this is unmaintainable. Any serious server project with more than 5 files would result in manually written wiring code. Using something like Googles Wire makes it much easier. A simple language should not have the goal to stick to a novice level of programmers.  – k_o_  Jul 5, 2022 at 13:00
    • 2 Still don't know why this answer was selected. It mixed two different things, language specifications, and programming patterns. In essence, it doesn't answer the original question it's just the author's opinion.  – Marlon Cristian  Jul 14, 2022 at 11:45
    • 1 Go's simplicity as a language does not mean it should only be used to write simple applications. As an app becomes more complex, a "DI is too complex for Go" mindset will quickly lead to "my Go app's init code is getting hard to maintain", and from there to "my application is too complex for Go" -- at which point you are forced to switch languages. This cannot be the correct stance; in the long term it will harm the Go community/ecosystem. Dependency injection can be done cleanly, with compile-time safety and without reflection (as in Google's Wire) if that's your preference.  – JakeRobb  Aug 25, 2022 at 19:35    

      Google's Wire looks promising. There're some articles about it:

       

      Uber's Dig is pretty awesome. Here's a great blog post about it: Dependency Injection in Go

       

       

      --------------------------------------------------------------------------------

Ioc是一個oop重要的程式設計思想。 此文帶著大家初探 IOC(控制反轉) , DI(依賴注入) ~~ 學一個技術或思想前我們最好先了解,這個技術或思想為我們解決怎樣問題。 Ioc—Inversion of Control 控制反轉 控制反轉是一個設計思想 ,把對於某個物件的控制權移轉給第三方容器 簡單解釋 A物件程式內部需要使用B物件 A,B物件中有依賴的成份 控制反轉是把原本A對B控制權移交給第三方容器 降低A對B物件的耦合性,讓雙方都倚賴第三方容器。 反轉概念如下圖 我們可發現有兩點差異 使用者原本直接耦合於A,但使用IoC容器使用者就直接對容器而不是A 至於A關連於誰由容器決定 原本A直接控制於B,C,但透過一個IoC容器我們控制權反轉給了容器 IoC經典實現對象設計法則 好萊塢法則:“別找我們,我們找你” 系統中模組建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。 DI—Dependency Injection 依賴注入 把被依賴物件注入被動接收物件中 案例解釋: 小明是個愛乾淨的人,但他工作時常加班導致房間雜亂,他不能忍受此狀況,所以小明去找一個清潔阿姨每天幫忙他打掃家裡 哪天阿姨哪天有事不能打掃,小明就必須要再去找人來幫忙打掃,由此可知小明耦合阿姨 ------------------------------------------------------------------------------------ 如果今天是.... 小明把他要的條件給「打掃仲介公司」,仲介公司幫他尋找有沒有符合小明需求的打掃阿姨,假如今天A阿姨請假了,仲介公司會自動找另一個符合需求B阿姨幫忙打掃... 原本小明需耦合於打掃阿姨,現在被「仲介公司」做了控制反轉讓「仲介公司」來提供打掃阿姨。 小明不用管是否今天有人會來打掃,「仲介公司」會幫小明找到一個掃地阿姨。 「仲介公司」可看作 依賴注入容器 「小明」可看作 被動接收物件 「打掃阿姨」可看作 被依賴物件 在使用IOC容器前需先了解雙方的依賴關係(誰依賴誰?) 上述還有一個很重要的觀念是,依賴和被接收對象要倚賴抽象。 範例使用:VS2015 IOC容器:AutoFac 下面範例來說明上面的例子 小明自己依賴於掃地阿姨 依賴程式碼寫在小明類別內部日後要更改只能動內部程式碼。 /// /// 小明直接依賴 Aunt 不是依賴抽象 /// 日後要改必須動內部 /// public class Mine { public Aunt aunt = new Aunt(); public void Room() { aunt.Swapping(); } } 呼叫使用時 Mine mine = new Mine(); mine.Room(); 小明找仲介公司 仲介公司(Ioc容器) 在仲介公司內註冊需求,讓仲介公司日後幫你找人(註冊的類別) /// /// 仲介公司 /// /// private static IContainer MiddleCompany() { ContainerBuilder builder = new ContainerBuilder(); //在仲介公司裡寫需求人申請單 builder.RegisterType(); //小明所需打掃阿姨需求 builder.RegisterType().As(); return builder.Build(); } 使用起來 IContainer middleCompany = MiddleCompany(); //仲介公司(IOC AutoFac)自動幫小明注入一個打掃阿姨 MineWithMiddle mineWithMiddle = middleCompany.Resolve(); mineWithMiddle.Room(); 總結: 系統中模組建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。 像網頁瀏覽器和伺服器是依賴Http協議,用戶端不管是手機.電腦,平板,伺服器端php,asp.net,java都可互相交信,依賴Http協議共用的合約 控制反轉:是一個設計思想 ,把對於某個物件的控制權移轉給共同第三方 依賴注入:把被依賴物件注入被動接收物件中 範例原始碼 :https://github.com/isdaniel/IOC_Sample 參考連結 : http://www.cnblogs.com/xdp-gacl/p/4249939.html

标签:小明,依賴,pattern,there,share,仲介公司,golang,阿姨,data
From: https://www.cnblogs.com/oxspirt/p/17096431.html

相关文章

  • (转)「Golang」for range 使用方法及避坑指南
    原文:https://blog.csdn.net/qq_37005831/article/details/114296008前言循环控制结构是一种在各种编程语言中常用的程序控制结构,其与顺序控制结构、选择控制结构组成了程......
  • (转)golang-标准库(math/rand)
    原文:https://itpika.com/2019/07/09/go/library-math-rand/rand包是go提供用来产生各种各样随机数的包,本文对这些产生随机数的方法做一下介绍。注意:rand生成的数值虽然说......
  • (转)深入golang -- select
    原文:https://zhuanlan.zhihu.com/p/509148906老规矩相信大家已经知道select应用的特性,这里主要是介绍select的底层原理。select底层原理主要分为两部:select语句......
  • (转)golang学习之--select--case 原理
    原文:https://blog.csdn.net/cyb_17302190874/article/details/108244683Go的select语句是一种仅能用于channl发送和接收消息的专用语句,此语句运行期间是阻塞的;当select中......
  • golang的闭包
    funcAddUpper()myFun{//闭包:返回的函数与这个函数引用到函数外的变量n形成一个整体,共同生成闭包,反复调用f1函数即AddUpper函数,n只初始化一次,所以返回的值的累加的......
  • 由Java正则表达式的灾难性回溯引发的高CPU异常:java.util.regex.Pattern$Loop.match
    问题与分析某天领导report了一个问题:线上的CPU自从上一个版本迭代后就一直处于居高不下的状况,领导看着这段时间的曲线图判断是有两条线程在不停的死循环。接到任务后去查看......
  • (转)golang常用库之-标准库 sync包| go语言如何实现单例模式、读写锁(sync.RWMutex)
    原文:https://blog.csdn.net/inthat/article/details/124218961golang常用库之-标准库sync包Golangsync包提供了基础的异步操作方法,包括互斥锁Mutex,执行一次Once和并发等......
  • (转)深入浅出Golang Runtime
    原文:https://www.cnblogs.com/lovezbs/p/14467801.html本文为腾讯NOW直播研发工程师郝以奋在8月19日深圳GopherMeetup上的分享,以下为根据PPT进行的详细注解。介绍......
  • (转)Golang标准库——runtime
    原文:https://www.jianshu.com/p/c1b6de70c004runtimeruntime包提供和go运行时环境的互操作,如控制go程的函数。它也包括用于reflect包的低层次类型信息;参见》reflect报......
  • golang变量
    1.golang变量命名规则由26个英文字母大小写,0-9,_组成。变量名不能以数字开头。变量都是先声明再使用,一旦声明必须使用。2.golang变量赋值方法2.1单个变量赋值......