Composition Over Inheritance in Go

Mary-Kate Olsen
Release: 2024-10-30 12:24:02
Original
365 people have browsed it

Composition Over Inheritance in Go

When designing software, the "composition over inheritance" principle often leads to more flexible, maintainable code. Go, with its unique approach to object-oriented design, leans heavily into composition rather than inheritance. Let's see why.

Why Go Prefers Composition

In traditional OOP languages, inheritance lets one class inherit behaviors and properties from another, but this can lead to rigid, hard-to-change hierarchies. Go avoids inheritance altogether and instead encourages composition—where types are built by combining smaller, focused components.

Composition in Action

Imagine we’re modeling a company with different types of workers: some are engineers, some are managers, and some are interns. Instead of creating a complex class hierarchy, we’ll define specific behaviors as independent types and then compose them.

Example: Worker Behaviors in Go

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")
}
Copy after login

Here:

  • Engineer and Manager embed Payable, giving them a Salary.
  • Manager also embeds Manageable, giving them team management abilities.
  • Each type implements Work() individually, satisfying the Worker interface.

Benefits of Composition

  • Simplicity: Each behavior is encapsulated in its struct, making it easy to extend.
  • Flexibility: New types or behaviors can be added without breaking existing code.
  • Reusability: Behaviors are modular, so we can easily combine them in different ways.

Using Interfaces with Composition

In Go, interfaces and composition work together to allow polymorphism without inheritance. Here’s how we can handle multiple worker types with a single function:

func DescribeWorker(w Worker) {
    w.Work()
}

func main() {
    engineer := Engineer{Payable{Salary: 80000}}
    manager := Manager{Payable{Salary: 100000}, Manageable{}}
    DescribeWorker(engineer)
    DescribeWorker(manager)
}
Copy after login

Go’s preference for composition over inheritance isn’t just a language quirk—it encourages cleaner, more modular code that’s adaptable to change. Instead of rigid hierarchies, you get flexible, reusable components that keep your codebase nimble and easy to maintain.

The above is the detailed content of Composition Over Inheritance in Go. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!