接口定义
应该定义在接口所使用的包中,而非接口实现的包中。
以io包中的io.Reader/io.Wirter为例,接口定义在io包中,而他的实现bytes.Buffer、os.File等都是在不同包中。
接口实现应该返回具体类型
应该返回对应的结构体
或指针
,这样实现类如果扩展新的方法就可以直接添加,无需改动接口定义部分,更加灵活。
//为了方便演示,本实例代码未遵循「接口需要在使用包中声明」规范
package demo
import "fmt"
type Demo interface {
show() error
}
type MyDemo struct {
}
//这里的返回值应该是 `MyDemo` 或 `*MyDemo` 而非 `Demo`
func NewMyDemo() *MyDemo {
return &MyDemo{}
}
func (md *MyDemo) show() error {
fmt.Println("show")
return nil
}
接口应该什么时候定义
在当前模块有依赖外部服务的时候,这时候就会定义一个接口,来对外部的依赖资源进行抽象解耦,屏蔽接口的实现。相反,依赖的提供方在不知道使用方需求的时候,定义接口也就没什么意义。