17 Feb 2020
SOLID principles of programming are a set of five design principles that help developers create code that is easy to maintain and extend over time.
You should be able to extend the behaviour of a class without modifying its existing code.
For example, instead of modifying the existing code of a class to add new functionality, you can create a new derived class that extends the behaviour of the base class.
For example:
Shape
Rectangle
. We should be able to replace an instance of Shape
with an instance of Rectangle
without affecting the correctness of the program. Any code that works with a Shape
should also work correctly with a Rectangle
.
For example, instead of having a single large interface that contains many methods, create smaller interfaces that each client can implement based on their specific requirements.
This helps to prevent clients from being burdened with unnecessary dependencies.
High-level modules should not directly depend on low-level modules. Instead, both high-level and low-level modules should depend on abstractions (interfaces or abstract classes).
For example, here we have a high-level class called ReportGenerator
and a low-level class called DatabaseConnection
. Without applying DIP, we have a direct dependency like this:
class ReportGenerator {
private DatabaseConnection databaseConnection;
public ReportGenerator() {
databaseConnection = new DatabaseConnection();
}
}
The ReportGenerator
class directly creates and depends on the DatabaseConnection
class. If DatabaseConnection
changes it can lead to changes in the ReportGenerator
class.
Now, applying DIP, we introduce an abstraction (interface) like DataStore
:
interface DataStore {
// Define methods common to data storage
}
class DatabaseConnection implements DataStore {
// Implement the DataStore interface
}
class ReportGenerator {
private DataStore dataStore;
public ReportGenerator(DataStore dataStore) {
this.dataStore = dataStore;
}
}