2. Open-Closed principle (OCP)
Prashanta Chakraborty
Fullstack developer | Next.js, React.js, Node.js, Nest.js Expert & GO Learner
Today I am talking about the Open-Closed principle.
2. Open-Closed principle (OCP): OCP says, that entities(Classes) should be open for extension and closed for modification. That means our class should be extendable without modifying the class.
Example 1:
public class Shape {
public void draw(String shapeType) {
if (shapeType.equals("Circle")) {
drawCircle();
} else if (shapeType.equals("Rectangle")) {
drawRectangle();
}
}
private void drawCircle() {
System.out.println("Drawing a Circle");
}
private void drawRectangle() {
System.out.println("Drawing a Rectangle");
}
}
Look at the example 1 here. We have a Shape class that has two methods: the first one is draw, the second one is drawCircle, and the last one is drawRectangle. Everything is okay so far. However, if I want to add another shape which is Triangle, I need to modify the Shape class. I would need to add an extra condition check in the draw method and also add another method, like this:
Example 2:
public class Shape {
public void draw(String shapeType) {
if (shapeType.equals("Circle")) {
drawCircle();
} else if (shapeType.equals("Rectangle")) {
drawRectangle();
} else if (shapeType.equals("Triangle")) {
drawTriangle();
}
}
private void drawCircle() {
System.out.println("Drawing a Circle");
}
private void drawRectangle() {
System.out.println("Drawing a Rectangle");
}
private void drawTriangle() {
System.out.println("Drawing a Triangle");
}
}
Take a look at Example 2, here we added an extra condition checking for Triangle and added drawTriangle method which means we modified our class, so this is a violation of OCP.
领英推荐
Example 3:
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class DrawingApp {
public void drawShape(Shape shape) {
shape.draw();
}
public static void main(String[] args) {
DrawingApp app = new DrawingApp();
Shape circle = new Circle();
Shape rectangle = new Rectangle();
app.drawShape(circle);
app.drawShape(rectangle);
}
}
In Example 3, we created an interface Shape, and the Circle, and Rectangle classes implement this interface, so we can have similar methods in the child classes. In that case, if we want to add one more shape, we don't need to modify our interface or the child classes.
Example 4:
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Triangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Triangle");
}
}
public class DrawingApp {
public void drawShape(Shape shape) {
shape.draw();
}
public static void main(String[] args) {
DrawingApp app = new DrawingApp();
Shape circle = new Circle();
Shape rectangle = new Rectangle();
Shape triangle = new Triangle();
app.drawShape(circle);
app.drawShape(rectangle);
app.drawShape(triangle);
}
}
For more: