Unravel › Java concepts › Design patterns and architecture
SOLID principles
SOLID is five guidelines for classes that are easy to change: single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion.
Learn these first
At a glance
Rules for building with LEGO: pieces that do one job, that connect through standard studs (interfaces), and that you can swap without rebuilding the whole model.
- 1S: a class should have one reason to changeA class that parses, validates, saves and emails has four. Split it.
- 2O: open for extension, closed for modification: add behaviour with a new class (a new DiscountStrategy) instead of editing a growing if/else
- 3L: a subclass must be usable wherever its parent is expected without surprisesA Square extends Rectangle that breaks setWidth violates it. Do not strengthen preconditions or weaken guarantees when overriding.
- 4I: many small, focused interfaces are better than one big one; no class should be forced to implement methods it does not use
- 5D: depend on abstractions, not on concrete classes: the service takes an OrderRepository interface, not JdbcOrderRepositoryConstructor injection (Spring) is how it is done.
- These are heuristics, not laws
- Dependency inversion is the one that pays off most visibly: it makes code testable (inject a fake) and replaceable (change the database or the HTTP client in one place)
- The mechanisms are the ordinary Java ones: interfaces and abstract classes, polymorphic calls, and constructors that receive collaborators
public class Notifications { interface MessageSender { void send(String to, String text); } static class EmailSender implements MessageSender { public void send(String to, String text) { System.out.println("mail to " + to + ": " + text); } } static class OrderService { private final MessageSender sender; OrderService(MessageSender sender) { this.sender = sender; } void confirm(String customer) { sender.send(customer, "order confirmed"); } }}Read the full explanation (about 2 min)
SOLID is five guidelines for classes that are easy to change: single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion. They explain why code is split into small interfaces and implementations.
A mental model
Rules for building with LEGO: pieces that do one job, that connect through standard studs (interfaces), and that you can swap without rebuilding the whole model.
How it works
S: a class should have one reason to change. A class that parses, validates, saves and emails has four. Split it.
O: open for extension, closed for modification: add behaviour with a new class (a new DiscountStrategy) instead of editing a growing if/else.
L: a subclass must be usable wherever its parent is expected without surprises. A Square extends Rectangle that breaks setWidth violates it. Do not strengthen preconditions or weaken guarantees when overriding.
I: many small, focused interfaces are better than one big one; no class should be forced to implement methods it does not use.
D: depend on abstractions, not on concrete classes: the service takes an OrderRepository interface, not JdbcOrderRepository. Constructor injection (Spring) is how it is done.
Going deeper
These are heuristics, not laws. Applied mechanically they produce piles of tiny classes and interfaces with a single implementation. Use them when change actually hurts: a class that you keep editing for different reasons, a test that needs the real database.
Dependency inversion is the one that pays off most visibly: it makes code testable (inject a fake) and replaceable (change the database or the HTTP client in one place).
Related ideas: composition over inheritance, "tell, don't ask", and keeping modules small with a clear public interface.
Under the hood
The mechanisms are the ordinary Java ones: interfaces and abstract classes, polymorphic calls, and constructors that receive collaborators. A DI container such as Spring only automates the wiring at start-up.
Common mistakes
- One interface for every class "just in case".
- Deep inheritance trees that break Liskov.
- Giant "manager" or "util" classes that do everything.
- Creating collaborators with
newinside the class that uses them.
How Unravel recognises it
When you paste code, Unravel looks for these signs of solid principles. Spotting them yourself is a good habit when you read unfamiliar code:
- Language constructs:
interfaceanon-class
Part of a learning path
- Design patterns and SOLID · previous: DAO and repository pattern
Related concepts
Frequently asked questions
What is SOLID principles?
SOLID is five guidelines for classes that are easy to change: single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion. They explain why code is split into small interfaces and implementations.
What are the most common mistakes with SOLID principles?
One interface for every class "just in case". Deep inheritance trees that break Liskov. Giant "manager" or "util" classes that do everything. Creating collaborators with new inside the class that uses them.
How can I see SOLID principles in real code?
Paste your own Java into Unravel and it will point out where solid principles appears, explain how it works at the detail level you choose, and draw the flow of the code around it.