062-一些 Go 接口设计建议

Posted --Allen--

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了062-一些 Go 接口设计建议相关的知识,希望对你有一定的参考价值。

Go 语言程序设计一书作者讲了一些关于 Go 语言面向对象编程的经验和建议,如果不拿过来太可惜了。

When designing a new package, novice Go programmers often start by creating a set of interfaces and only later define the concrete types that satisfy them. This approach results in many interfaces, each of which has only a single implementation. Don’t do that. Such interfaces are unnecessary abstractions; they also have a run-time cost. You can restrict which methods of a type or fields of a struct are visible outside a package using the export mechanism (§6.6). Interfaces are only needed when there are two or more concrete types that must be dealt with in a uniform way.

每当设计一个新的 package 的时候,那些没有经验的新手程序员总是先定义一堆接口,然后再定义一些具体的类型去实现这些接口(译者注:大佬开始吐槽了)。结果导致一堆接口,每个接口却只有一个具体类型去实现了它。别在这么搞下去了(译者注:能想象作者已经被新手程序员搞疯了,哈哈),特么有必要这样折腾吗?你搞这么多接口,运行时也是一种损耗啊哥哥们!像这种只有一个具体类型实现的接口,完全没必要再用接口了,你可以充分利用 Go 语言 package 的导出机制的嘛!那些不想导出的方法你给屏蔽掉,只导出你需要的方法不就 OK 的嘛。什么?你问我啥时候需要用接口?如果你的接口被 2 个或 2 个以上的具体类型实现,就考虑用接口吧。(译者注:国内程序员经常吐槽程序里接口满天飞的情况。)

We make an exception to this rule when an interface is satisfied by a single concrete type but that type cannot live in the same package as the interface because of its dependencies. In that case, an interface is a good way to decouple two packages.

凡事有特例。有一种情况,就是这个接口被另一个(些)包依赖,而你的类型 T 没办法和它们写在同一个包里(译者注:通常是一些包的作者提前写好的代码,你当然没办法把你的类型 T 强势插入他们的包),此时接口可以只被这一个具体类型 T 实现(依赖反转)。这样做的好处是可以将你的包和其它包进行解耦。

Because interfaces are used in Go only when they are satisfied by two or more types, they necessarily abstract away from the details of any particular implementation. The result is smaller interfaces with fewer, simpler methods, often just one as with io.Writer or fmt.Stringer. Small interfaces are easier to satisfy when new types come along. A good rule of thumb for interface design is ask only for what you need.

通常 Go 里的接口都被 2 个或更多的具体类型实现,所以有必要从具体实现中抽象(出共性)。这样做的后果就是导致接口里的方法会更少,更精简。典型的比如 io.Writer/fmt.Stringer 这些接口。接口越简单,越容易被满足。一个比较好的接口设计经验法则——只考虑你需要的东西。


到此为止,interface 就告以段落。很期待下一章 —— Goroutine & Channel.

以上是关于062-一些 Go 接口设计建议的主要内容,如果未能解决你的问题,请参考以下文章

Go -- type 和断言 interface{}转换

Go 语言为何不受待见?

Go设计模式-工厂模式

[08]Go设计模式:代理模式(ProxyPattern)

访问数据库

[翻译]Go与C#对比 第三篇:编译运行时类型系统模块和其它的一切