设计模式顾名思义他只是一种代码设计的程式,一种套路,跟编程语言是没有关系的,那为什么我们通常都是听到写Java的人在讲这种模式,但是写 go 的这部分人为什么很少听到他们讲设计模式呢?这个我个人感觉各种语言跟他的个性是有关系的, 因为 java 当年推出来他作为面向对象的始作俑者,他要非常旗帜鲜明的去倡导,面向对象这种思想,所以呢哪怕你是写一个hello world 你也必须先写一个 class ,那么几乎离了 class 你什么事都做不了,这就导致他把很多简单的事情给复杂化了,本来一个函数可以解决,非要搞一个类,那 go 呢作为一个后起之秀,它当然是看到了之前各种前辈的这种弊端,他的一个设计哲学就是要简单,简单,简单。
那么很多人在 go 发展的这段时间之内呢,给它提了很多建议,希望它加各种各样的功能,但是都被go官方给拒绝了,就是因为他们觉得 go 要保持简单,这个秉性。我们都知道 go 语言可以像 c 语言那样,全部使用函数式编程,也可以使用这些类 struct ,面向对象去编程。实际上在我们工程当中,我们去完成一个业务需求,你完全使用函数,完全使用 c 那一套也是可以的。通过使用面向对象,像这种struct,interface 这种东西的话,可以使你的代码看上去更加简洁,规整的比较好,如果说你的业务流程会更加复杂,那么你的这种代码复用程度比较高的话,这个时候你使用面向对象就可以降低代码的冗余程度,这是面向对象的第二个好处。说到这个地方其实也还谈不上什么设计模式,也仅仅是用了些基本的面向对象的技巧。当你看到一个写 go 的人,在代码中用了设计模式,他可能仅仅是因为学了设计模式,所以想把他用起来,为了用而用。其实当你的业务发展几年后,你会发现你的业务仍然没有发展到,你最初设想的那么复杂,那么你当初用了设计模式,他的优势是没有体现出来的,但是并不是告知你在设计阶段的时候可以疏忽。
其实在 go 语言中有一种模式是非常常见的,你会发现这种模式其实是随处可见的,这种模式称之为 option模式
。
pacakge main
type Pool struct {
Cap int
Host string
}
func WithCap(n int) func(*Pool) { // 众所周知在 golang 中函数也是一种数据类型。注意一定要传递指针
return func(p *Pool) { // 返回函数类型
p.Cap = n // 函数里套函数,所以这里可以取到两个函数的参数,一个WithCap函数上下文,嵌套一个匿名函数上下文,所以函数的变量可以被匿名函数读取
}
}
type PoolOption func(*Pool) // 定义一个函数签名
func WithCap(n int) PoolOption {
return func(p *Pool) {
p.Cap = n
}
}
func WhitHost(h string) PoolOption {
return func(p *Pool) {
p.Host = h
}
}
func NewPool(options ...PoolOption) *Pool {
pool := new(Pool)
for _, f := range options {
f(pool)
}
return pool
}
func main() {
f := NewPool(
WhitCap(1),
WhitHost("localhost"),
)
}