Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Learn Polymorphism via Embedded Interfaces | Composition and Idiomatic Patterns
Struct-Based Design in Go

bookPolymorphism via Embedded Interfaces

Swipe to show menu

When you embed an interface in a struct in Go, you enable that struct to satisfy the interface implicitly, while also allowing the struct to delegate behavior to any concrete implementation of the interface. This technique is a cornerstone of idiomatic Go design, especially for achieving polymorphism in backend systems. By embedding interfaces, you can swap out different implementations at runtime or during testing, leading to flexible and maintainable code. This pattern is especially useful for abstracting dependencies such as storage backends, logging, or external services, giving your application the ability to adapt to changing requirements without significant refactoring.

main.go

main.go

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
package main import ( "fmt" ) // Storage interface defines methods for a storage backend. type Storage interface { Save(key string, value string) error Load(key string) (string, error) } // FileStorage is a concrete implementation of Storage. type FileStorage struct { data map[string]string } func NewFileStorage() *FileStorage { return &FileStorage{data: make(map[string]string)} } func (fs *FileStorage) Save(key string, value string) error { fs.data[key] = value return nil } func (fs *FileStorage) Load(key string) (string, error) { val, ok := fs.data[key] if !ok { return "", fmt.Errorf("key not found") } return val, nil } // Service embeds the Storage interface for flexible backends. type Service struct { Storage } func main() { fileStorage := NewFileStorage() service := Service{Storage: fileStorage} err := service.Save("user42", "Alice") if err != nil { fmt.Println("Save error:", err) return } val, err := service.Load("user42") if err != nil { fmt.Println("Load error:", err) return } fmt.Println("Loaded value:", val) }

Embedding interfaces in structs is a powerful pattern for dependency injection and extensibility. By accepting any implementation of an interface, your struct becomes decoupled from specific dependencies, making it easy to swap out or mock those dependencies for testing. This approach also allows you to extend your application by introducing new implementations without modifying existing code, supporting the open/closed principle. In backend service design, embedding interfaces leads to more modular, testable, and maintainable systems.

question mark

Which of the following best describes the role of embedded interfaces in backend service design in Go?

Select the correct answer

Everything was clear?

How can we improve it?

Thanks for your feedback!

Sectionย 3. Chapterย 3

Ask AI

expand

Ask AI

ChatGPT

Ask anything or try one of the suggested questions to begin our chat

Sectionย 3. Chapterย 3
some-alt