Golang 模式 - 第一部分
大家好!
今天的目标是描述并记录一些 Golang 模式。
正如您从我之前的帖子(go concurrency和go lambdas)中了解到的那样,我最近进入了 Go 领域,并很快发现我从以前的经验中所了解的常见习语并不完全适用于 golang。
嗯,我发现有些模式非常常见,依我拙见,应该作为 Golang 初学者指南的一部分介绍。
示例中的所有代码都在GitHub上。
组常数
标题说明了一切,我们希望将公共常量分组在同一个命名空间中。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
// Package constants shows a pattern to group constants together | |
package constants | |
// Endpoint contains the endpoint configuration | |
var Endpoint struct { | |
Hostname string | |
Port int | |
} | |
func init() { | |
Endpoint.Hostname = "some-endpoint" | |
Endpoint.Port = 9090 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
// Package constants shows a pattern to group constants together | |
package constants | |
// Endpoint contains the endpoint configuration | |
var Endpoint struct { | |
Hostname string | |
Port int | |
} | |
func init() { | |
Endpoint.Hostname = "some-endpoint" | |
Endpoint.Port = 9090 | |
} |
链
一个供应商链,一旦其中一个供应商返回非零结果或错误,它就会立即返回。
代码展示了一个示例,其中我们需要从以下可能的来源之一加载配置值:环境变量、配置文件或数据库。
我们希望一旦返回非零结果,就停止搜索配置值。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package chain | |
import "fmt" | |
func ExampleChain() { | |
endpoint, _ := chain( | |
loadEndpointFromConfigFile, | |
loadEndpointFromEnvVariables, | |
loadEndpointFromDatabase, | |
).get() | |
fmt.Println(endpoint) | |
// Output: some-endpoint | |
} | |
func loadEndpointFromEnvVariables() (string, error) { | |
return "", nil | |
} | |
func loadEndpointFromConfigFile() (string, error) { | |
return "", nil | |
} | |
func loadEndpointFromDatabase() (string, error) { | |
return "some-endpoint", nil | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package chain | |
import "fmt" | |
func ExampleChain() { | |
endpoint, _ := chain( | |
loadEndpointFromConfigFile, | |
loadEndpointFromEnvVariables, | |
loadEndpointFromDatabase, | |
).get() | |
fmt.Println(endpoint) | |
// Output: some-endpoint | |
} | |
func loadEndpointFromEnvVariables() (string, error) { | |
return "", nil | |
} | |
func loadEndpointFromConfigFile() (string, error) { | |
return "", nil | |
} | |
func loadEndpointFromDatabase() (string, error) { | |
return "some-endpoint", nil | |
} |
此处 为链的代码。
选项
Options 展示了一种灵活的对象构造方法。
其主要优点是将来可以向对象构造函数添加更多参数,而不会破坏客户端。
在其他语言中,你可能会使用重载构造函数或回退到构建器模式。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Context("Greeting with no Name option", func() { | |
It("returns default greeting", func() { | |
greeting := NewGreeting() | |
Expect(greeting.get()).To(Equal("Hello Stranger")) | |
}) | |
}) | |
Context("Greeting with Name option", func() { | |
It("returns custom greeting", func() { | |
greeting := NewGreeting(Name("Mickey")) | |
Expect(greeting.get()).To(Equal("Hello Mickey")) | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Context("Greeting with no Name option", func() { | |
It("returns default greeting", func() { | |
greeting := NewGreeting() | |
Expect(greeting.get()).To(Equal("Hello Stranger")) | |
}) | |
}) | |
Context("Greeting with Name option", func() { | |
It("returns custom greeting", func() { | |
greeting := NewGreeting(Name("Mickey")) | |
Expect(greeting.get()).To(Equal("Hello Mickey")) | |
}) | |
}) |
此处 为选项的代码。
或许
Maybe 是一个可能包含或不包含非空值的容器。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Context("User present", func() { | |
var greeting string | |
MaybeUser(getUser(1)).IfPresent(func(u *User) { | |
greeting = "Hello " + u.name | |
}) | |
It("greets the user", func() { | |
Expect(greeting).To(Equal("Hello Mickey")) | |
}) | |
}) | |
Context("User absent", func() { | |
var greeting string | |
MaybeUser(getUser(-1)).WhenAbsent(func() { | |
greeting = "Hello stranger" | |
}) | |
It("greets the user", func() { | |
Expect(greeting).To(Equal("Hello stranger")) | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Context("User present", func() { | |
var greeting string | |
MaybeUser(getUser(1)).IfPresent(func(u *User) { | |
greeting = "Hello " + u.name | |
}) | |
It("greets the user", func() { | |
Expect(greeting).To(Equal("Hello Mickey")) | |
}) | |
}) | |
Context("User absent", func() { | |
var greeting string | |
MaybeUser(getUser(-1)).WhenAbsent(func() { | |
greeting = "Hello stranger" | |
}) | |
It("greets the user", func() { | |
Expect(greeting).To(Equal("Hello stranger")) | |
}) | |
}) |
函数类型
函数是 Golang 中的“一等公民”。每当我们想要轻松实现策略模式或类似功能时,都可以将其用作类型。
这种模式在 golang http 包中被广泛使用。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package functiontype | |
import "fmt" | |
type Greeting func(name string) string | |
func GreetingService(request Request, greeting Greeting) string { | |
return fmt.Sprintf("Service says: %s", greeting(request.user)) | |
} | |
func ExampleFunctionType() { | |
request := Request{user: "Mickey"} | |
fmt.Println( | |
GreetingService(request, func(name string) string { | |
return fmt.Sprintf("Hola %s!", name) | |
}), | |
) | |
// Output: Service says: Hola Mickey! | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
package functiontype | |
import "fmt" | |
type Greeting func(name string) string | |
func GreetingService(request Request, greeting Greeting) string { | |
return fmt.Sprintf("Service says: %s", greeting(request.user)) | |
} | |
func ExampleFunctionType() { | |
request := Request{user: "Mickey"} | |
fmt.Println( | |
GreetingService(request, func(name string) string { | |
return fmt.Sprintf("Hola %s!", name) | |
}), | |
) | |
// Output: Service says: Hola Mickey! | |
} |
结论
感谢阅读!
如果您发现它有用,请告诉我,或者是否有一个关键模式确实应该成为此列表的一部分。
鏂囩珷鏉ユ簮锛�https://dev.to/napicella/golang-patterns-5a64