Any project has a scope of changes in terms of features, functionalities and workflows. Practically, to design application prefactly from begining is almost impossible even in the agile development. Classes and interfaces are pillers of application designs.
SOLID is one of the proven set of design principles that are meant to guide developers to design and build robust, easily maintainable and scalable software.
This article is focused ont he second principle of SOLID : The principle of Open / Closed.
It satates that : Software entities (ie. classes, interfaces, functions etc) should be Open to extended but closed for modifications.
Lets Check first what does it mean by this principle.
A class is closed since it may be compiled, stored in the library, baselined and used by client classes. But it is also open, since any new class may use it as parent and adding new features.
Fortunately we have a concept of Inheritance to achieve this goal. But, inheritance introduces tight coupling if the subclasses depend on implementation details of their parent class.
my recomandation is to start designe inheritance with interfaces instead of superclasses. The interfaces are closed for modifications, you can provide new implementations to extend the functionality of your software.
Let’s see an example that uses the Open/Closed Principle.
We will need a Employee interface, the Company class, which uses the Employees, and some implementation of the Employee interface.
The Company class should know just one thing about the Employees — what methods to call. This is what all the Employees have in common, so we will have a Employee interface with just the common methods(ie. someWork).
public interface Employee{
public void someWork();
}
And a Company class that encapsulates an Employye implementation and executes it.
public class Company() {
private Employee emp;
// we set the strategy in the constructor
public Company(Employee emp) {
this.emp = emp;
}
public void completeTheWork() {
this.emp.someWork();
}
}
And let’s create two implementations for the Employee interface.
public class Employee1 implements Employee {
public void someWork() {
System.out.println(“Work of Emoloyee 1”);
}
}
public class Employee2 implements Employee {
public void someWork() {
System.out.println(“Work of Emoloyee 2”);
}
}
Now lets use some dependency Injection to see how it works. We need to create one Perform class.
public class Perform() {
public static void main(String[] args) {
Context context = new Company(new Employee1()); // we inject the Employee1
context.completeTheWorky(); // it will print “Execute employee 1”;
context = new Company(new Employee2()); // we inject the Employee2
context.completeTheWork(); // it will print “Execute employee 2”
}
}
So the Company is decoupled from a specific Employee class. You could implement many Employees it needed and no matter how they work and what you want them to do, you don’t need to modify the Company class. The Company class knows just that it must call someWork method and it is enough.
After taking a closer look at the Single Responsibility Principle, we now discussed the Open/Closed Principle.
It uses Interfaces to enable you the functionality of your application without changing the existing code.
0 Comment