我正在开发一个严重依赖基础代码库的项目。在基本代码中,有一个名为eventWatcher
的接口(在此简化)//Baselibrary.go:
package base
type eventHandle interface {
eventHookTypeA
eventHookTypeB
someOtherMethod() results
}
type eventHookTypeA interface {
// method definitions
HandleEventA() results
}
type eventHookTypeB interface {
// method definitions
HandleEventB() results
}
func handleEvents(eventType string, handle eventHandle) results {
if eventType == "eventA" {
return handle.HandleEventA()
} else if eventType == "eventB" {
return handle.HandleEventB()
}
return nil
}
对于我们的项目,我们现在有第三种事件类型(例如eventTypeC),它是我们项目独有的。一种方法是在基类中添加第三个接口定义(eventHookTypeC),并在我们自己的项目代码中相应地实现。然而,我们的CI环境也将采用这个新版本的Baselibrary.go并使用它构建所有其他项目,这将失败,因为它们将缺少eventHookTypeC的impl。
除了更改我们的构建环境或repo之外,是否有一个Go解决方法,而无需更改其他项目的代码?
答案 0 :(得分:8)
你可以像使用例如http.Pusher
或io.Closer
。使用“可选”方法创建新接口,并传递原始接口。当您想要执行可选方法时,使用类型断言来检查您所拥有的值是否实现了另一个接口,如果是,则调用该方法。
type eventHandle interface {
eventHookTypeA
eventHookTypeB
// DON'T add TypeC interface.
someOtherMethod() results
}
type eventHookTypeA interface {
// method definitions
HandleEventA() results
}
type eventHookTypeB interface {
// method definitions
HandleEventB() results
}
type eventHookTypeC interface {
HandleEventC() results
}
func handleEvents(eventType string, handle eventHandle) results {
if eventType == "eventA" {
return handle.HandleEventA()
} else if eventType == "eventB" {
return handle.HandleEventB()
} else if eventType == "eventC" {
if c,ok := handle.(eventHookTypeC); ok {
return c.HandleEventC()
} else {
log.Println("somewhat bad happen")
}
}
return nil
}