Open-closed principle states that
software entities such as classes, methods should be open for extension and
closed for modification. That is we can extend the behavior of software entity,
without touching the source code of the entity.
For example, there is a class ‘ConnectionFactory’,
it provides number of methods to connect to databases like MySQL, MongoDB,
Elasticsearch etc., Assume there are number of classes using this
ConnectionFactory. Even if you change single line in ConnectionFactory class, you need to retest all the modules that are using ConnectionFactory
class. If you design your code like this, you will end up in testing all the
dependent modules often.
Open-closed principle solved this
problem in straightforward way.
Rule
1: Design a module such
that, it never change.
Rule
2: When requirements
change, extend (Inheritance) the behavior of an entity by adding new code.
Modules that
follow above two rules are open for extension and closed for modification.
How
can I achieve open-closed principle?
Using abstraction and inheritance.
For example, I am developing a drawing
board application. My initial requirement is, user can able to draw a circle
and triangle. I am going to design using open-closed principle.
public interface Shape { void draw(); }
public class Circle implements Shape{ @Override public void draw() { System.out.println("Drawn Circle"); } }
public class Triangle implements Shape{ @Override public void draw() { System.out.println("Drawn Triangle"); } }
import java.util.List; public class DrawUtil { public static void drawShapes(List<Shape> shapes){ shapes.stream().forEach(Shape::draw); } }
import java.util.*; public class Main { public static void main(String args[]){ List<Shape> shapes = new ArrayList<> (); shapes.add(new Circle()); shapes.add(new Triangle()); shapes.add(new Triangle()); DrawUtil.drawShapes(shapes); } }
Run
Main.java, you will get following output.
Drawn Circle
Drawn
Triangle
Drawn
Triangle
Now user wants to draw squares also.
Since we followed open-closed principle, we can add this functionality without
touching existing modules. Define a class Square that implements Shape class, that’s
it you are done.
public class Square implements Shape { @Override public void draw() { System.out.println("Drawn Square"); } }
import java.util.*; public class Main { public static void main(String args[]){ List<Shape> shapes = new ArrayList<> (); shapes.add(new Circle()); shapes.add(new Triangle()); shapes.add(new Triangle()); shapes.add(new Square()); DrawUtil.drawShapes(shapes); } }
Output
Drawn Circle
Drawn
Triangle
Drawn
Triangle
Drawn Square
References
https://en.wikipedia.org/wiki/Open/closed_principle
No comments:
Post a Comment