英文:
Why database types aren't interface in GO
问题
强调使用接口而不是具体类型,以便使代码更容易进行测试。不过,我想知道为什么在 sql 包中的类型(如 DB 或 Rows)没有采用这种方式。为了模拟这些依赖项,我不得不创建自己的接口,以便编写单元测试(而不是集成测试)。难道不应该以这种方式测试面向 DB 的代码吗?
英文:
There is an emphasis on using interfaces instead of concrete types in order to make the code easier to test. I wonder though why this wasn't done for the types in the sql package like DB or Rows. In order to mock those dependencies I had to create my own interfaces so that I could write unit tests (not integration tests). Aren't DB facing code supposed to be tested that way?
答案1
得分: 1
在公共 API 中暴露接口而不是具体类型会增加在添加接口方法时破坏其他人代码的风险。
以 os.File
为例。如果 os.File
是一个接口,它将是一个具有 17 个公共方法的接口。添加第 18 个方法将会破坏所有定义了自己类型并实现了 os.File
接口的人的代码。相比之下,向当前的 os.File
结构体添加第 18 个方法不会破坏任何接受 io.Reader
、io.Writer
或任何其他定义了 os.File
方法子集的接口的方法。它也不会破坏模拟这些 io.Reader
和 io.Writer
接口的测试代码。
因此,如果你希望其他人定义自己的实现,就在公共 API 中暴露接口。否则,暴露一个具体类型,并让人们使用他们所需方法子集定义自己的接口,这些接口由你的具体类型实现。
英文:
Exposing interfaces in your public API instead of concrete types increases the risk of breaking other peoples code when you add methods to the interface.
See for example os.File
. If os.File
was an interface it would be an interface with 17 public methods. Adding an 18th method would break everyone who defined their own types that implemented the os.File
interface. In contrast, adding an 18th method to the current os.File
struct won't break any methods taking an io.Reader
, io.Writer
or any other interface that defines a subset of the methods of an os.File
. It also won't break test code which mocks these io.Reader
and io.Writer
interfaces.
So expose an interface in your public API if you want other people to define their own implementations of them. Otherwise expose a concrete type and let people define their own interfaces implemented by your concrete type using only the subset of methods they need.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论