Go 围棋中的包解耦
我们都知道依赖注入使包解耦。 但我对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
假设包用户需要访问配置包。
我们可以将配置对象传递给用户方法。这样,只要新代码解析接口,我就可以更改配置包功能。 另一种方法是直接调用配置包方法,在这些场景中,只要方法名称保持不变,我也可以更改配置代码。像这样 更新: 这两种方法有什么不同之处:
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