- Expert Android Programming
- Prajyot Mainkar
- 444字
- 2021-07-08 10:29:14
Open-Closed Principle
The Open-Closed Principle states that:
Software entities (classes, modules, functions, etc) should be open for extension, but closed for modification.
This principle basically states that we have to design our modules, classes, and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code
Now let us discuss the Open-Closed Principle in the following example.
Let us assume we are trying to calculate the area of some shapes. So let's take the example of a rectangle and a circle. The classes for these have been formed in the following code:
public class Rectangle { private double length; private double height; // getters/setters ... } public class Circle { private double radius; // getters/setters ... }
So a common function used to calculate the area of both the rectangle and the circle would look something like this:
public class AreaManager { public double calculateArea(ArrayList<Object>... shapes) { double area = 0; for (Object shape : shapes) { if (shape instanceof Rectangle) { Rectangle rect = (Rectangle)shape; area += (rect.getLength() * rect.getHeight()); } else if (shape instanceof Circle) { Circle circle = (Circle)shape; area += (circle.getRadius() * cirlce.getRadius() * Math.PI; } else { throw new RuntimeException("Shape not supported"); } } return area; } }
As can be seen from the preceding function, as new shapes are introduced, the calculateArea function will grow bigger and lots of handling and changes will be required. This violates the Open/Closed Principle
A way to resolve this is by using a common interface:
public interface Shape { double getArea(); }
Both the rectangle and circle can implement this interface by which the method to calculate the area will remain inside the object class instead of the AreaManager.
So now the rectangle and circle classes will look something like this:
public class Rectangle implements Shape { private double length; private double height; // getters/setters ... @Override public double getArea() { return (length * height); } } public class Circle implements Shape { private double radius; // getters/setters ... @Override public double getArea() { return (radius * radius * Math.PI); } }
Now, as the methods for calculating the areas are present inside the objects, the AreaManager will look something like this:
public class AreaManager { public double calculateArea(ArrayList<Shape> shapes) { double area = 0; for (Shape shape : shapes) { area += shape.getArea(); } return area; } }
Now we can calculate the total area without ever needing to change the calculateArea method. The same shape interface can be now used in new classes to calculate the area without changing the AreaManager.