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

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.

主站蜘蛛池模板: 宁化县| 全州县| 新乐市| 白沙| 金平| 平度市| 和平县| 芮城县| 慈利县| 沙洋县| 浦北县| 依安县| 大竹县| 乳源| 十堰市| 宁蒗| 卢湾区| 永胜县| 靖远县| 五台县| 清徐县| 平泉县| 云南省| 凌云县| 平原县| 荥阳市| 扬中市| 阿拉善盟| 安新县| 山阴县| 外汇| 敦煌市| 九龙县| 民权县| 西乌珠穆沁旗| 武隆县| 邹平县| 峨眉山市| 三明市| 从江县| 淮安市|