在设计软件时,“组合优于继承”原则通常会带来更灵活、可维护的代码。 go 以其独特的面向对象设计方法,严重依赖于组合而不是继承。让我们看看为什么。
为什么 go 更喜欢组合
在传统的 oop 语言中,继承允许一个类从另一个类继承行为和属性,但这可能会导致僵化的、难以更改的层次结构。 go 完全避免继承,而是鼓励组合——通过组合更小的、集中的组件来构建类型。
行动中的作文
想象一下,我们正在为一家拥有不同类型员工的公司建模:有些是工程师,有些是经理,有些是实习生。我们不会创建复杂的类层次结构,而是将特定行为定义为独立类型,然后组合它们。
示例:go 中的 worker 行为
package main import "fmt" type worker interface { work() } type payable struct { salary int } func (p payable) getsalary() int { return p.salary } type manageable struct{} func (m manageable) manage() { fmt.println("managing team") } type engineer struct { payable } func (e engineer) work() { fmt.println("engineering work being done") } type manager struct { payable manageable } func (m manager) work() { fmt.println("managerial work being done") }
登录后复制
这里:
- 工程师和经理嵌入 payable,给他们发薪水。
- manager 还嵌入了 manageable,赋予他们团队管理能力。
- 每种类型单独实现 work(),满足 worker 接口。
组合的好处
- 简单性:每个行为都封装在其结构中,使其易于扩展。
- 灵活性:可以在不破坏现有代码的情况下添加新类型或行为。
- 可重用性:行为是模块化的,因此我们可以轻松地以不同的方式组合它们。
使用组合接口
在 go 中,接口和组合协同工作,允许多态性而无需继承。以下是我们如何使用单个函数处理多种工作类型:
func DescribeWorker(w Worker) { w.Work() } func main() { engineer := Engineer{Payable{Salary: 80000}} manager := Manager{Payable{Salary: 100000}, Manageable{}} DescribeWorker(engineer) DescribeWorker(manager) }
登录后复制
go 对组合而不是继承的偏好不仅仅是一种语言怪癖——它鼓励更干净、更模块化、能够适应变化的代码。您可以获得灵活、可重用的组件,而不是僵化的层次结构,从而使您的代码库保持灵活且易于维护。
以上就是Composition Over Inheritance in Go的详细内容,更多请关注php中文网其它相关文章!