首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang接口-实现循环依赖关系

Golang接口-实现循环依赖关系
EN

Software Engineering用户
提问于 2022-03-15 19:20:10
回答 2查看 797关注 0票数 0

在尝试将接口与实现分离时,我遇到了一个循环依赖问题.

Java世界中有一个最佳实践:使用接口而不是具体的类。也就是说,与其声明ArrayList<int>类型的变量,不如使用List<int>类型。这样,从ArrayList迁移到您自己的List实现将是无痛的。

为了好玩,我决定在戈朗写一个事件队列/公共汽车。使用者能够订阅某些主题并在特定主题中发布事件。

我已经决定将接口和实现分开,以防将来不得不为已经存在的解决方案(如RabbitMQ )编写适配器。

首先,我定义了接口:

代码语言:javascript
复制
package eventQueue

type EventQueue interface {
    Subscribe(topic string, handlerFunc HandlerFunc)
    Publish(topic string, event interface{})
}

type HandlerFunc func(event interface{})

而且,在internal包中,我编写了基本实现:

代码语言:javascript
复制
package internal

import (
    "eventQueue"
    "sync"
)

type EventQueueImpl struct {
    handlerFuncsByTopic map[string][]eventQueue.HandlerFunc
    mutex sync.RWMutex
}

// Implements the interface...

回到接口--我编写了一个New()方法,它返回默认实现(当然,目前只有一个):

代码语言:javascript
复制
func New() EventQueue {
    return &internal.EventQueueImpl{} // EventQueueImpl uses pointer receivers
}

它就在这里。EventQueueImpleventQueue导入HandlerFunceventQueue包导入EventQueueImpl

如何将此设计更改为在保持接口实现分离的同时避免循环依赖?

依赖注入是一个合适的解决方案吗?

EN

回答 2

Software Engineering用户

发布于 2022-03-16 08:31:44

在接口而不是实现中放置构造函数的原因是什么?

构造函数返回一个实现而不是接口,接口永远不应该被实例化,只有它们的具体实现应该实例化。

票数 2
EN

Software Engineering用户

发布于 2022-03-17 16:06:21

与Java相比,您应该看到New()函数是您的结构的构造函数。而且,与Java中的构造函数一样,该函数应该使用实现,而不是接口。

New()函数是特定于实现的;如果internal.EventQueueImpl需要一些需要设置或初始化的内部属性才能使用,那么New()就是设置它的地方--但是EventQueue接口的其他一些随机实现不需要这些属性,这意味着New()正在做一些事情来使internal.EventQueueImpl工作,因此在eventQueue包中定义它是没有意义的。

New()不应该成为eventQueue包的一部分的另一个迹象是,如果要添加第二个eventQueue.EventQueue实现,您会做什么?创建eventQueue.New2()?更改New()的签名以接受某种切换?如果这样做,您将如何处理所有不同实现的配置?

因此,正如f222所说,要解决这个问题,您所需要做的就是将New()eventQueue迁移到internal,这一切都会很好。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/437392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档