官术网_书友最值得收藏!

What does this mean for Go?

In Chapter 1Never Stop Aiming for Better, we mentioned the popular Go idiom coined by Jack Lindamoodaccept interfaces, return structs. Combine this idea with the ISP and things start to take off. The resultant functions are very concise about their requirements and, at the same time, they are quite explicit regarding their outputs. In other languages, we might have to define the outputs in the form of an abstraction or create adapter classes to decouple our function from our users entirely. However, given Go's support for implicit interfaces, there is no need for this.

Implicit interfaces are a language feature whereby the implementor (that is, the struct) does not need to define the interfaces that it implements, but rather only needs to define the appropriate methods to satisfy the interface, as shown in the following code:

type Talker interface {
SayHello() string
}

type Dog struct{}

// The method implicitly implements the Talker interface
func (d Dog) SayHello() string {
return "Woof!"
}

func Speak() {
var talker Talker
talker = Dog{}

fmt.Print(talker.SayHello())
}

This might seem like a neat trick to cut down on typing, and it is. However, that is not the only reason to use it. When using explicit interfaces, the implementing object becomes somewhat coupled with its dependents as there is a rather explicit link between them. However, perhaps the most significant reason is simplicity. Let's look at one of the most popular interfaces in Go that you've probably never heard of:

// Stringer is implemented by any value that has a String method, which 
// defines the “native” format for that value. The String method is used
// to print values passed as an operand to any format that accepts a
// string or to an unformatted printer such as Print.

type Stringer interface {
String() string
}

This interface might not look impressive, but the fact that the fmt package supports this interface allows you to do the following:

func main() {
kitty := Cat{}

fmt.Printf("Kitty %s", kitty)
}

type Cat struct{}

// Implicitly implement the fmt.Stringer interface
func (c Cat) String() string {
return "Meow!"
}

If we had explicit interfaces, imagine how many times we would have to declare that we implement Stringer. Perhaps where implicit interfaces give us the most significant advantage in Go is when they are combined with the ISP and DI. The combination of the three allows us to define input interfaces that are thin, specific to the particular use case, and decoupled from everything else, as we saw with the Stringer interface.

Furthermore, defining interfaces in the package in which they are used narrows the scope of knowledge required to work on a piece of code, which in turn makes it much easier to understand and test.

主站蜘蛛池模板: 漯河市| 大城县| 临武县| 七台河市| 抚州市| 江陵县| 平和县| 正定县| 兴义市| 肥东县| 山阳县| 新建县| 陇南市| 金华市| 库尔勒市| 景洪市| 兴化市| 都江堰市| 新蔡县| 孟连| 十堰市| 大新县| 舞阳县| 汕尾市| 花莲市| 淮北市| 通城县| 施秉县| 木里| 巴林右旗| 福安市| 南昌县| 新干县| 台前县| 开原市| 余姚市| 巨鹿县| 古田县| 阿拉善左旗| 商城县| 定州市|