Composition Over Inheritance
Veeg om het menu te tonen
Go takes a unique approach to structuring code by favoring composition over inheritance. In many object-oriented languages such as Java or C++, you might use inheritance to create relationships between classes, allowing a subclass to inherit methods and fields from a parent. However, inheritance often leads to rigid class hierarchies that can be difficult to change or extend over time. Go deliberately avoids inheritance, encouraging you to build complex behaviors by composing small, focused types together. This makes your codebase more modular, easier to test, and more adaptable to evolving requirements.
main.go
123456789101112131415161718192021222324252627282930313233package main import ( "fmt" "time" ) // Logger provides logging capabilities. type Logger struct{} func (l Logger) Log(message string) { fmt.Printf("[%s] %s\n", time.Now().Format(time.RFC3339), message) } // Service composes Logger to gain logging functionality. type Service struct { Logger Name string } func (s Service) DoWork() { s.Log("Service " + s.Name + " is starting work.") // ... perform some work ... s.Log("Service " + s.Name + " has finished work.") } func main() { service := Service{ Logger: Logger{}, Name: "EmailSender", } service.DoWork() }
By embedding one struct within another, as you see with Service embedding Logger, you enable code reuse without tying your types into a rigid hierarchy. This approach lets you mix and match capabilities as needed, leading to more flexible backend architectures. You can add logging, metrics, or other cross-cutting concerns to any struct simply by embedding the relevant type, rather than forcing all your services to inherit from a single base class. This pattern is idiomatic in Go and helps you build systems that are both robust and easy to extend.
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.