Go中高低层模块通信机制:RelationshipBrowser与Relationships关联原理
问题解答
Go语言的接口采用隐式实现机制,和Java等需要显式写implements XxxInterface的语言不同,Go没有要求类型主动声明自己实现了哪个接口,只要一个类型的方法集完全匹配某接口定义的所有方法签名,编译器就会自动判定该类型实现了这个接口,二者的关联完全由Go编译阶段自动完成,不需要手动写绑定逻辑。
结合你的代码场景拆解
- 你定义的
RelationshipBrowser接口,仅约束了一个方法签名:FindAllChildrenOf(name string)[]*Person - 你给
*Relationships(也就是Relationships的指针类型)声明了接收者方法FindAllChildrenOf,方法签名和接口定义的完全一致,因此Go编译器会自动判定:*Relationships类型实现了RelationshipBrowser接口 - 你在
main函数中初始化Research结构体时,传入了&relationships(也就是*Relationships类型的实例)给browser字段:因为browser是RelationshipBrowser接口类型,而&relationships刚好实现了这个接口,所以这个赋值是合法的。此时接口变量browser内部会存储两个信息:实际类型为*Relationships、实际值为你创建的relationships实例的指针。 - 当你在
Investigate方法中调用r.browser.FindAllChildrenOf时,Go会根据接口变量存储的实际类型,自动调度到*Relationships对应的FindAllChildrenOf实现,所以能正确执行你写的逻辑。
补充说明
这正是你代码注释里提到的**依赖倒置原则(DIP)**的Go语言实现:高层模块Research不需要直接依赖低层模块Relationships,只需要依赖抽象的RelationshipBrowser接口。后续如果你要替换关系存储的实现(比如从内存切片改成数据库查询),只要新的类型实现了RelationshipBrowser接口,Research的Investigate方法不需要做任何修改,完全解耦了高低层模块。
内容的提问来源于stack exchange,提问作者DSL
相关产品推荐
相关产品推荐

