# SOLID Principles ## Summary SOLID is a set of five fundamental principles for object-oriented software design introduced by Robert C. Martin in 2000. These principles help create more maintainable, flexible, and scalable software systems. Each letter in SOLID represents a specific principle that addresses common software design challenges and promotes best practices in code organisation. Key benefits: - Reduces dependencies between components - Makes code easier to maintain and modify - Supports better testing practices - Enhances code reusability - Promotes cleaner architecture ## Details ### Single Responsibility Principle (SRP) A class should have one, and only one, reason to change. This means each class should focus on a single responsibility or concern. Benefits: - Simpler testing with fewer test cases - Lower coupling between components - Better code organisation - Easier maintenance Example: Instead of having a Book class that handles both book properties and printing: ```java // Good: Separate classes for different responsibilities public class Book { private String name; private String author; private String text; public String replaceWordInText(String word, String replacement) { return text.replaceAll(word, replacement); } } public class BookPrinter { void printTextToConsole(String text) { // Printing logic } void printTextToAnotherMedium(String text) { // Other output logic } } ``` ### Open-Closed Principle (OCP) Software entities should be open for extension but closed for modification. This encourages adding new functionality through new code rather than changing existing code. Benefits: - Reduces risk of bugs in existing code - Maintains backward compatibility - Promotes code reuse - Supports incremental development Example: ```java public class Guitar { private String make; private String model; private int volume; // Base functionality } public class SuperCoolGuitarWithFlames extends Guitar { private String flameColor; // Extended functionality without modifying original } ``` ### Liskov Substitution Principle (LSP) Subtypes must be substitutable for their base types without altering the correctness of the program. This ensures that inheritance is used correctly. Benefits: - Maintains consistent behavior - Ensures proper inheritance hierarchies - Prevents unexpected side effects - Supports code reusability Example: ```java public interface Car { void accelerate(); void brake(); } public class ElectricCar implements Car { public void accelerate() { // Electric acceleration } public void brake() { // Electric braking with regeneration } } public class PetrolCar implements Car { public void accelerate() { // Petrol engine acceleration } public void brake() { // Traditional braking } } ``` ### Interface Segregation Principle (ISP) Clients should not be forced to depend on interfaces they don't use. This promotes creating focused, specific interfaces rather than large, general-purpose ones. Benefits: - Reduces code coupling - Improves maintainability - Makes interfaces more focused - Prevents unnecessary implementation Example: ```java // Instead of one large interface: public interface BearKeeper { void washTheBear(); void feedTheBear(); void petTheBear(); } // Break into specific interfaces: public interface BearCleaner { void washTheBear(); } public interface BearFeeder { void feedTheBear(); } ``` ### Dependency Inversion Principle (DIP) High-level modules should not depend on low-level modules. Both should depend on abstractions. This principle promotes loose coupling through dependency injection and interface-based design. Benefits: - Enables better testing - Supports modularity - Facilitates change - Promotes reusability Example: ```java // Instead of: public class Windows98Machine { private final StandardKeyboard keyboard; private final Monitor monitor; public Windows98Machine() { keyboard = new StandardKeyboard(); monitor = new Monitor(); } } // Better approach: public interface Keyboard {} public interface Monitor {} public class Windows98Machine { private final Keyboard keyboard; private final Monitor monitor; public Windows98Machine(Keyboard keyboard, Monitor monitor) { this.keyboard = keyboard; this.monitor = monitor; } } ``` ## 🔗 Related Resources - [[Clean Code]] - Principles for writing maintainable code - [[Design Patterns]] - Common software design patterns - [[Object Oriented Design]] - Fundamentals of OOP design