我有一个关于依赖注入(inject)的问题。 请考虑以下示例。
例如,selector() 是一个选择某些东西并保证返回一个接口(interface)的函数
在这个例子中
bar.node.go
type NodeTemplate struct {
Name string
}
// satisfy interface declared in db.foo.go
//but never imports anything from db.foo.go
func (node *NodeTemplate) GetUuidName() string {
if node != nil {
return node.Name
}
return
}
db.foo.go
// interface declared in db.foo.go
type Node interface {
GetUuidName() string
}
选项A //因此 selector 接收到 Some interface 的 map 并填充 map
func SelectSomething(nodemap map[string]Node, selectFactor string) {
// selection from db and result populate in a map
}
选项B
另一种模式 SelectSomething 返回一个节点 及其接口(interface)
所以另一个包将依赖于导入 Node 这将引入依赖关系。
func SelectSomething(seleconsomething) []*Node {
// do selection and return a slice of SomeInterface
n := &Node{} // here it need to be concret type T
return Node
}
因此,根据我所描述的逻辑,我发现第一种方法更好,但在该方法中,选择需要进行具体类型分配才能填充 map 。
考虑另一个例子
db.foo.go
type Node interface {
GetUuidName() string
}
func inserter(node *Node) error {
// do some work
node.GetUuidName()
}
对于像 inserter 的情况,inserter 没有外部依赖,inserter 只需要接收满足接口(interface)的东西。在本地声明接口(interface)并消除依赖性。
但在选择器示例的情况下,它必须进行内存分配才能返回或填充映射或返回具有具体类型 T 的内容。因此在这两种情况下,它都必须具有内部重新表示。
所以我的问题是选择器能否在运行时以某种方式根据接口(interface)确定它接收的类型并实例化该类型的对象并将其作为接口(interface)插入映射或返回接口(interface)的一部分。 ?
通过这样做,选择器函数将不依赖于它接收到的内容,它只是保证它会实例化相同的对象类型 T 和返回界面。
或者选择器可以返回接口(interface),但我想我必须在 db 包和包 X 之间有一个双向接口(interface),或者动态调度程序需要做一些魔术?
最佳答案
您希望一个类型以某种方式表现。这是通过接口(interface)实现的。这种情况也不异常(exception)。只需将所需的行为添加到您的界面,如下面的 Foo
界面所示。
package main
import (
"fmt"
"reflect"
)
type Foo interface {
Bar()
TypeOf() reflect.Type
}
type Baz struct{}
func (b Baz) Bar() {
fmt.Println("I am a Fooer!")
}
func (b Baz) TypeOf() reflect.Type {
return reflect.TypeOf(b)
}
func DoSomeThing(f Foo) {
f.Bar()
fmt.Println(f.TypeOf())
}
func main() {
fmt.Println("Hello, playground")
b := Baz{}
DoSomeThing(b)
}
关于go - 通用方法和建议如何消除依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57941502/