For this blog post, I wanted to delve into what the SOLID principles are and how they apply to object oriented programming. SOLID is an acronym for the 5 object oriented design principles. They are the single-responsibility principle, the open-closed principle, the Liskov substitution principle, the interface segregation principle, and the dependency inversion principle. The reason these principles are important, and why they’re important to use is that they help to maintain good coding practices and help to avoid code smells. This is essential in large projects, as code smells and bad design could increase development time, make refactoring harder, and make development harder for teams if other team members couldn’t understand the code.
The first principle of SOLID is the Single-Responsibility Principle. It states that a class should have only one reason to change, and that it should have only one job. This means that a class should only have code related to its function, and not extraneous code that should be elsewhere that’s unrelated to the class’s intended purpose. This helps to keep classes simple and easy to understand. If a class contained logic unrelated to its purpose, then it would make the intended purpose of the class confusing.
The second principle of SOLID is the Open-Closed Principle. It states that a class should be open for extension but closed for modification. This means that a class should be designed in such a way that if a modification to that class is needed, it can instead be extended by a different class, and then that class could be modified while maintain the functionality of the original class. The also helps the make each class have its own specific purpose. If instead of creating a new class, a single class was modified every time a modification was needed, then the class would get messy very fast, making it hard to read and hard to understand its functionality.
Next, the Liskov Substitution principle states that every subclass that extends another class should be substitutable for the parent class. This means that for example, if there was a shape class, and then a square class extended the shape class, then the square class should be able to be used in place of the shape class.
Then, the Interface Segregation Principle states that classes shouldn’t be forced to use an interface which has functionality that it has no use for. This means that if an interface has some functionality that doesn’t apply to everything, then a class shouldn’t use that interface if it won’t be using that functionality. Instead, interfaces should be very broad, making them applicable for many different purposes.
Finally, the Dependency Inversion Principle states that functionality should depend upon abstractions, not concrete methods. This means that if you have a class that must perform some functionality, and it shouldn’t depend on an exact implementation, then the class must be design in such a way that it applies to all implementations, based off abstractions.