Interfaces and implementations
Interfaces and implementations are fundamental concepts that let you write flexible, testable code. An interface defines what something does, while an implementation defines how it does it. This separation is the foundation of clean architecture.
- An interface is the "what." It's a contract. A promise. It tells you what a thing can do, but it has zero clue how it's done. Think of a power outlet on your wall. You know you can plug a lamp into it and get electricity (the "what"). You don't need to know about the power plant, the transformers, or the squirrels running on a wheel that generate the power (the "how"). The outlet is the interface.
- An implementation is the "how." This is the messy reality. It's the actual code that does the work promised by the interface. It's the power plant, the wiring in your walls, and maybe even that poor squirrel. It's the concrete class that has the methods and logic.
| Concept | Analogy | In Code |
|---|---|---|
| Interface | The wall socket | public interface LightSwitch |
| Implementation | The power grid | public class EdisonPowerGrid implements LightSwitch |
Why should I care?
Your code becomes flexible
Let's say you start by faking a UserRepository that just returns a hardcoded list of users. Your implementation is simple. But your application code doesn't care. It just talks to the UserRepository interface.
Later, when you're ready to use a real database, you just create a PostgresUserRepository. You swap out the implementation. The rest of your code? It doesn't change. At all. You just changed the "how" without touching the "what."
Testing becomes easy
If your BillingService needs a PaymentGateway to work, you don't want to hit a real credit card API every time you run a unit test. That's slow, expensive, and gets you angry emails from accounting.
Instead, you give it a mock implementation of the PaymentGateway interface. A fake one that just pretends to work. This lets you test your BillingService in isolation, and it's fast and free.
It hides the ugly parts
Real-world code is messy. Implementations deal with database connections, weird API quirks, and all sorts of other headaches. An interface is a clean, beautiful facade that hides all that complexity. It lets other developers use your component without needing to understand the intricate details inside.
This pattern appears throughout Spring Boot. From repositories to services to external APIs, you'll see interfaces defining contracts and implementations handling the specifics. Understanding this separation helps you write code that's easier to maintain, test, and evolve over time.