Master the Six Core OOP Principles: A Practical SOLID Guide
This article introduces the six fundamental object‑oriented design principles—SRP, OCP, LSP, DIP, ISP, and LoD—explains their definitions, benefits, and real‑world Java examples, and shows how they together form the SOLID guidelines for clean software architecture.
This is the opening article of a design‑pattern series, summarizing the six essential object‑oriented design principles that underpin the SOLID guidelines.
Single Responsibility Principle – SRP
Open/Closed Principle – OCP
Liskov Substitution Principle – LSP
Dependency Inversion Principle – DIP
Interface Segregation Principle – ISP
Law of Demeter – LoD
Single Responsibility Principle
The SRP states that a class should have only one reason to change, meaning it should handle a single responsibility. If a class manages multiple unrelated methods, changes to one may unintentionally affect the other, so responsibilities should be split into separate classes.
Benefits: reduces class complexity, improves readability and maintainability, and limits the impact of changes to the class itself.
Open/Closed Principle
The OCP asserts that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. When requirements evolve, we should extend existing code rather than modify it, minimizing the risk of introducing new bugs.
A common way to achieve this is to define abstractions (interfaces or abstract classes) for the framework and implement details in concrete subclasses.
Liskov Substitution Principle
LSP requires that objects of a superclass can be replaced with objects of a subclass without altering the desirable properties of the program.
In practice, a subclass can extend the behavior of its parent but must not change the parent’s contract.
Subclass may implement abstract methods but must not override concrete ones.
Subclass can add its own methods.
When overriding, method parameters must be more permissive.
Return types must be covariant (more specific).
LSP promotes building abstractions first and then extending details, often working hand‑in‑hand with the Open/Closed Principle.
Dependency Inversion Principle
DIP advocates that high‑level modules should not depend on low‑level module implementations; both should depend on abstractions. In Java, this means coding to interfaces rather than concrete classes.
public class Hammer {
public String function() {
return "use hammer to fix things";
}
}
public class Worker {
public void fix(Hammer hammer) {
System.out.println("Worker " + hammer.function());
}
public static void main(String[] args) {
new Worker().fix(new Hammer());
}
}To make the worker independent of a specific tool, we introduce an interface:
public interface Tools {
String function();
} public class Worker {
public void fix(Tools tool) {
System.out.println("Worker " + tool.function());
}
public static void main(String[] args) {
new Worker().fix(new Hammer());
new Worker().fix(new Screwdriver());
}
} public class Hammer implements Tools {
public String function() { return "use hammer to fix things"; }
}
public class Screwdriver implements Tools {
@Override
public String function() { return "use screwdriver to fix things"; }
}This interface‑based design greatly improves extensibility and reduces coupling.
Interface Segregation Principle
Clients should not be forced to depend on interfaces they do not use.
Instead of a large interface with many methods, split it into smaller, role‑specific interfaces so that implementing classes only need to provide the methods they actually require.
Law of Demeter (Least Knowledge Principle)
An object should only talk to its immediate friends.
Only objects that are directly related (passed as parameters, held as member variables) should be accessed; distant objects should be reached via intermediaries, reducing coupling.
For example, a worker asks a shopkeeper for a CD without caring how the shopkeeper obtains it; the worker communicates only with the shopkeeper, not with the shopkeeper’s suppliers.
Conclusion
The six OOP principles help manage changing requirements by minimizing the amount of code that needs to be altered and limiting the ripple effect of changes. While they provide valuable guidance, they are not strict formulas; applying them wisely requires experience to avoid over‑engineering.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
