Java世界中有一个最佳实践:使用接口而不是具体的类。也就是说,与其声明ArrayList<int>类型的变量,不如使用List<int>类型。这样,从ArrayList迁移到您自己的List实现将是无痛的。
为了好玩,我决定在戈朗写一个事件队列/公共汽车。使用者能够订阅某些主题并在特定主题中发布事件。
我已经决定将接口和实现分开,以防将来不得不为已经存在的解决方案(如RabbitMQ )编写适配器。
首先,我定义了接口:
package eventQueue
type EventQueue interface {
Subscribe(topic string, handlerFunc HandlerFunc)
Publish(topic string, event interface{})
}
type HandlerFunc func(event interface{})而且,在internal包中,我编写了基本实现:
package internal
import (
"eventQueue"
"sync"
)
type EventQueueImpl struct {
handlerFuncsByTopic map[string][]eventQueue.HandlerFunc
mutex sync.RWMutex
}
// Implements the interface...回到接口--我编写了一个New()方法,它返回默认实现(当然,目前只有一个):
func New() EventQueue {
return &internal.EventQueueImpl{} // EventQueueImpl uses pointer receivers
}它就在这里。EventQueueImpl从eventQueue导入HandlerFunc,eventQueue包导入EventQueueImpl。
依赖注入是一个合适的解决方案吗?
发布于 2022-03-16 08:31:44
在接口而不是实现中放置构造函数的原因是什么?
构造函数返回一个实现而不是接口,接口永远不应该被实例化,只有它们的具体实现应该实例化。
发布于 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,这一切都会很好。
https://softwareengineering.stackexchange.com/questions/437392
复制相似问题