1 Go语言设计哲学
1.1 少即是多
Go语言没有犯C++的错误,没有过度地追求语言特性的大而全,而是最大限度地控制语言特性的数量,控制语言使用的复杂性。二八定律在编程语言中可以描述为80%的代码仅使用20%的语言特性。增加语言特性并不能开发效率的提升,原因是它会增加复杂性,导致使用者更容易犯错;有些复杂的语言特性可以通过库的其他形式来辅助支持。所以,在Go语言中,没有看到运算符重载,没有看到多重继承等不太实用的语言特性。
少即是多还隐含另一个概念就是语言特性的正交性。几何上的正交指的是两个向量的垂直关系,一个向量在另一个向量方向上的投影是一个点。现实中的正交是指多个因子,一个发生变化,不会影响其他因子的变化。在不减少表现力的情况下,正交是保持事物稳定性和简单性的最好设计。Go语言很好遵循了这个规律,Go的多个特性都是正交的,比如 goroutine、接口、类型系统等。这些语言特性组合在一起使用使Go语言的表现力大增,但并没有增加语言使用的复杂性,这是“少即是多”的临沂城含义。
只提供一个方法做事情,把事情做到极致,这是 Go 的设计思想之一。可以在很多地方看到这种设计思想的体现:比如循环只提供了一个 for 关键字,没有必要引入 while、do...while,一个关键字就能解决的事情没有必要造多个轮子。
1.2 世界是并行的
整个宇宙、时间就是一个维度,万物并行存在,万事并行发生。Go 语言原生支持并发,更容易对并行世界建模,更容易解决并行世界里的问题域。
1.3 组合优于继承
世界是由万物组合而成的。微观世界里物质由分子组合而成,分子由原子组合而成,原子由原子核和核外电子组成;在人类社会中,一个家庭由多个人组合成的,一个班级是由多个同学组合成的,一个办公室是由多个员工组合成的。我们日常是由的手机、汽车都是由一个个零部件组合而成的。继承关系在世界万物的关系中只是一个非常小的子集,组合才是世间万物基本的、常见的关系。所以以继承为基础的面向对象编程语言存在表现力不足,最后不得不搞出一套设计模式来弥补这个缺陷。Go语言选择的是组合的思想,这是和现实世界万物关系比较吻合的设计思路,表现力更强。Go 语言编程中不会有所谓的23种设计模式,Go语言使用很自然的方式来建模世界,解决问题。
1.4 非侵入式的接口
计算机界有一句经典的名言:“计算机科学领域的任何问题都可以通过增加一个间接的中间件来解决”(Any problem in cimputer science can be sovled by another layer of indirection)。在软件设计领域,层与层之间的解耦可以通过“接口”来实现,分层是计算机编程领域的战略指导思想,接口是分层实现的一种重要战术手段。
Go语言接口采用的是一种 Duck 模型,具体类型不需要显式地声明自己实现了某个接口,只要其方法集是接口方法集的超集即可。至于判断类型是否实现接口则完全交给编译器去处理,这显然是一种更先进的方式,它是接口和实现者彻底解耦,在接口和实现之间不需要强关联了。这完全符合软件开发的基本流程,好的软件不是一次写成的,而不断迭代重构的产物。在最初设计阶段,可能完全没有使用接口,后来抽象出接口,再后来具体类型实例实现了更多的方法,又抽象出更复杂的接口。Go的接口可以组合新接口,这个特性使得Go程序的迭代和重构非常容易。人不是上帝,没有上帝视角,显式的接口声明显然要求人具备上帝视角,整个接口继承体系一开始就要进行精心和周全的设计。很多没有 Duck 模型接口模型的语言类库的设计往往很复杂,设计者需要从上帝视角设计类库,因为一旦接口和继承关系确定了,后续很难再优雅地改动。而Go语言则不同,Go倾向于小粒度的接口设计,通过接口组合,自由组合成新的接口,这和人类对世界基本认知的过程是一致的,便于后续代码的重构和优化。
1.5 总结
Go语言不像 Java 那样,宗教式地完全面向对象设计。完全面向对象设计有时并不能很好地描述这个世界。Java 就好比手里握着锤子,看什么都是钉子,这与现实世界不符。类描述单个事物还可以,一旦表示多个事物间的交互和复杂关系,其表现力就会遇到挑战,最后通过设计模式进行弥补。设计模式不是因为语言优秀带来的副产品,而是因为语言表现力不足而不得不依赖经验积累进行弥补。Go是面向工程的实用主义者,其继承了面向对象、函数式和过程式等各个编程范式语言的优点,使用函数、接口、类型组合、包等简单的语言特性,组合产生强大的表现力,可以轻松地构建大规模程序。
是时候转变观念了,不要一提编程就说面向对象,一提面向对象就谈设计模式。编程的世界是多样的,编程思想和范式是丰富多彩的。Go语言之所以有这么好的设计,是因为其规避了前面各种语言踩过的坑,吸收了许多优秀编程语言中好的语言特性。作为新语言没有太多历史包袱,又能从历史语言中吸取经验和教训,新语言只会越来越优秀,这不足为奇。改进生产工具,提升生产力,应该是每个程序员不懈追求的东西,Go语言恰巧就是这么一种能快速提升生产力的编程语言。
参考
《Go语言核心编程》