Questions
What are interfaces and how are they used in Go?
The Scenario
You are a backend engineer at a fintech company. You are building a new service that needs to be able to process payments from a variety of different payment providers, such as Stripe, PayPal, and Braintree.
You need to find a way to write your code so that it is not tightly coupled to any specific payment provider.
The Challenge
Explain what interfaces are in Go and how you would use them to solve this problem. What are the key benefits of using interfaces?
A junior engineer might try to solve this problem by writing a separate function for each payment provider. This would be a very verbose and difficult to maintain solution.
A senior engineer would know that interfaces are the perfect tool for this job. They would be able to explain what interfaces are and how to use them to write code that is not tightly coupled to any specific payment provider.
Step 1: Understand What Interfaces Are
An interface is a collection of method signatures. A type implements an interface by implementing all the methods in the interface.
In Go, interfaces are implemented implicitly. This means that you do not need to explicitly declare that a type implements an interface.
Step 2: Define an Interface
Here’s how we can define an interface for our payment providers:
type PaymentProvider interface {
Pay(amount float64) error
}Step 3: Implement the Interface
Next, we can implement the interface for each of our payment providers:
type Stripe struct{}
func (s Stripe) Pay(amount float64) error {
// ... (Stripe payment logic) ...
return nil
}
type PayPal struct{}
func (p PayPal) Pay(amount float64) error {
// ... (PayPal payment logic) ...
return nil
}Step 4: Use the Interface
Finally, we can write a function that takes the PaymentProvider interface as an argument:
func processPayment(p PaymentProvider, amount float64) error {
return p.Pay(amount)
}
// ...
stripe := Stripe{}
processPayment(stripe, 100.0)
paypal := PayPal{}
processPayment(paypal, 100.0)By using an interface, we can write code that is not tightly coupled to any specific payment provider. This makes our code more flexible and easier to maintain.
Practice Question
You have a function that takes an `io.Reader` as an argument. Which of the following can you pass to this function?