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

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.

主站蜘蛛池模板: 江津市| 改则县| 嵊泗县| 民勤县| 双城市| 林甸县| 恩施市| 江安县| 格尔木市| 封开县| 凭祥市| 淳化县| 赫章县| 武清区| 安图县| 桐乡市| 肇州县| 廊坊市| 额济纳旗| 弋阳县| 克山县| 马鞍山市| 屏山县| 远安县| 察隅县| 岑巩县| 淄博市| 台湾省| 平湖市| 额尔古纳市| 巴彦淖尔市| 四会市| 高安市| 永和县| 珠海市| 抚远县| 琼海市| 安泽县| 贵阳市| 黄龙县| 海宁市|