Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 围棋中的包解耦_Go_Design Patterns_Dependency Injection_Solid Principles_Decoupling - Fatal编程技术网

Go 围棋中的包解耦

Go 围棋中的包解耦,go,design-patterns,dependency-injection,solid-principles,decoupling,Go,Design Patterns,Dependency Injection,Solid Principles,Decoupling,我们都知道依赖注入使包解耦。 但我对go中依赖注入的最佳实践有点困惑。 假设包用户需要访问配置包。 我们可以将配置对象传递给用户方法。这样,只要新代码解析接口,我就可以更改配置包功能。 另一种方法是直接调用配置包方法,在这些场景中,只要方法名称保持不变,我也可以更改配置代码。像这样 更新: 这两种方法有什么不同之处: package User func foo(config ConfigObject) { config.Foo() } 还有这个: package User impor

我们都知道依赖注入使包解耦。 但我对go中依赖注入的最佳实践有点困惑。
假设包用户需要访问配置包。
我们可以将配置对象传递给用户方法。这样,只要新代码解析接口,我就可以更改配置包功能。 另一种方法是直接调用配置包方法,在这些场景中,只要方法名称保持不变,我也可以更改配置代码。像这样

更新: 这两种方法有什么不同之处:

package User

func foo(config ConfigObject) {
   config.Foo()
}
还有这个:

package User

import Config

func foo() {
   config.Foo()
}

在方法的
config
参数上调用
config.Foo
意味着您收到某个结构的实例(可能实现接口
config
),并在该实例/接口上调用方法
Foo
。可以将此视为用OO术语调用对象的方法:

package user

func foo(cfg config.Config) {
   cfg.Foo()
}

调用
config.Foo
导入
config
包意味着您正在调用包
config
的函数
Foo
,而不是任何对象/结构/接口的函数。将其视为没有任何对象的纯过程编程:

package user

import config

func foo() {
   config.Foo()
}
后者与依赖注入无关,如果
Config
是一个接口,则前者可能构成依赖注入的一部分

另一方面,依赖注入在Go中通常遵循与其他语言相同的规则:

接受接口,提供实现

因为in-Go结构隐式地而不是显式地满足接口(Java就是这样)

  • 接受值的代码只需要了解接口并导入它
  • 实现它的代码甚至不需要知道接口的相关信息(只要满足它就可以了)
  • 将impl提供给接受 显然,接口需要同时了解这两个方面
例如,这意味着:

package config

type Config interface {
    Foo() string
}

package foo

type Foo struct{}

func (f *Foo) Foo() string {
    return "foo"
}

package boo

type Boo struct{}

func (b *Boo) Foo() string {
    return "boo" 
}

package main

func foo(cfg config.Config) string{
    return cfg.Foo()
}

func main() {
    // here you inject an instance of Foo into foo(Config)
    
    log.Print(foo(&foo.Foo{}))

    // here you inject an instance of Boo into foo(Config)
    log.Print(foo(&boo.Boo{})
}
印刷品

2018/03/03 13:32:12富

2018/03/03 13:32:12 boo


在方法的
config
参数上调用
config.Foo
意味着您收到某个结构的实例(可能实现接口
config
),并在该实例/接口上调用方法
Foo
。可以将此视为用OO术语调用对象的方法:

package user

func foo(cfg config.Config) {
   cfg.Foo()
}

调用
config.Foo
导入
config
包意味着您正在调用包
config
的函数
Foo
,而不是任何对象/结构/接口的函数。将其视为没有任何对象的纯过程编程:

package user

import config

func foo() {
   config.Foo()
}
后者与依赖注入无关,如果
Config
是一个接口,则前者可能构成依赖注入的一部分

另一方面,依赖注入在Go中通常遵循与其他语言相同的规则:

接受接口,提供实现

因为in-Go结构隐式地而不是显式地满足接口(Java就是这样)

  • 接受值的代码只需要了解接口并导入它
  • 实现它的代码甚至不需要知道接口的相关信息(只要满足它就可以了)
  • 将impl提供给接受 显然,接口需要同时了解这两个方面
例如,这意味着:

package config

type Config interface {
    Foo() string
}

package foo

type Foo struct{}

func (f *Foo) Foo() string {
    return "foo"
}

package boo

type Boo struct{}

func (b *Boo) Foo() string {
    return "boo" 
}

package main

func foo(cfg config.Config) string{
    return cfg.Foo()
}

func main() {
    // here you inject an instance of Foo into foo(Config)
    
    log.Print(foo(&foo.Foo{}))

    // here you inject an instance of Boo into foo(Config)
    log.Print(foo(&boo.Boo{})
}
印刷品

2018/03/03 13:32:12富

2018/03/03 13:32:12 boo