Interfaces for Polymorphism
Swipe to show menu
Go interfaces provide a powerful mechanism for achieving polymorphism and decoupling in backend design. An interface in Go is a type that specifies a set of method signatures. Any type that implements those methods automatically satisfies the interface, without needing explicit declarations. This allows you to write functions and components that operate on abstractions, not concrete types, leading to more modular and testable code.
The syntax for declaring an interface uses the type keyword, followed by the interface name and the interface keyword. Inside the curly braces, you define the required method signatures. For instance, you might define an interface for sending notifications, where any type that implements the Notify method satisfies the interface.
Go developers commonly use interfaces to abstract dependencies, such as repositories, services, or external APIs. This enables you to swap implementations easily and write unit tests using mocks or stubs. It is idiomatic in Go to define small, focused interfaces that describe a single behavior, rather than large, catch-all interfaces.
notifier.go
123456789101112131415161718192021222324252627282930313233343536373839package main import "fmt" // Notifier interface defines a single method Notify type Notifier interface { Notify(message string) } // EmailNotifier implements Notifier type EmailNotifier struct { EmailAddress string } func (e EmailNotifier) Notify(message string) { fmt.Printf("Sending email to %s: %s\n", e.EmailAddress, message) } // SMSNotifier implements Notifier type SMSNotifier struct { PhoneNumber string } func (s SMSNotifier) Notify(message string) { fmt.Printf("Sending SMS to %s: %s\n", s.PhoneNumber, message) } // SendAlert accepts any Notifier and uses it to send a message func SendAlert(n Notifier, message string) { n.Notify(message) } func main() { email := EmailNotifier{EmailAddress: "user@example.com"} sms := SMSNotifier{PhoneNumber: "+1234567890"} SendAlert(email, "Your order has shipped!") SendAlert(sms, "Your code is 123456.") }
By using interfaces, you can decouple your code from specific implementations. In the example above, the SendAlert function only depends on the Notifier interface, not on EmailNotifier or SMSNotifier directly. This means you can add new types of notifiersโsuch as push notifications or webhooksโwithout changing the SendAlert function. Interfaces also make it easier to write tests, since you can pass in mock implementations that record calls or simulate failures. This flexibility is a core strength of Go's approach to polymorphism and leads to backend code that is easier to maintain, extend, and test.
Thanks for your feedback!
Ask AI
Ask AI
Ask anything or try one of the suggested questions to begin our chat