In the previous post Object Oriented Design Principles (OODP): Open-Closed Principle(OCP) of the series OODP, we have seen how we can achieve the OCP using Shape object like Square, Circle. In this blog post, we will see how we can use the Open-Closed Principle in business scenario.

As noted in the previous post thumb rule for OCP is: We can add new features in the module without changing the existing code (CLOSED) but by adding new code (OPEN).

 

Requirement:
There is a need for a data upload program to create a sales order. Flat file would be the source of the data for this program. We are getting some fields in the flat file like Customer number, Material number, Plant etc. Obviously, it is required to validate the input before calling the BAPI to create the sales order. For this example, we would concentrate on the validation part. We will use the polymorphism to achieve the OCP for this requirement.

 

UML diagram would look like this:

image

 

To realize this requirement, we would create an interface LIF_SUBOBJ for common methods which we can use in different classes like Customer LCL_KUNNR, Material LCL_MATNR, etc. Definition of the interface and interface impelementing classes:

 

Method IS_VALID in the customer class LCL_KUNNR validates the customer number against the customer master KNA1. Method IS_VALID in the material class LCL_MATNR validates the material number against the material master MARA.
Implementation for these classes LCL_KUNNR, LCL_MATNR:

 

Public attribute LT_OBJ of class LCL_SO is an internal table which holds the reference of different objects like Customer LCL_KUNNR, Material Number LCL_MATNR etc. Method VALIDATE_KEYS of the class LCL_SO calls the method IS_VALID of each object reference of the table LT_OBJ attribute. We will use down cast from the object reference in LT_OBJ to object reference of LIF_SUBOBJ. Definition and Implementation of the sales order class LCL_SO is:

 

Full code sinppet of the program could be found here. For completion purpose, I have included local class based exception in this coding.

 

Change in Requirement:
After successful validation of the object, it required to set some attributes of the each object. E.g. set the customer name attribute of the object customer. We will achieve this added requirement without any modification of the method VALIDATE_KEYS.

By adding a new method SET_ATTRIBUTES in the interface LIF_SUBOBJ, it will be available in all implementing classes like LCL_KUNNR, LCL_MATNR. Call this method inside the LOOP of objects after key validation in the method VALIDATE_KEYS. Updated UML will look like this:

image

And updated code snippet can be found here.

 

Conclusion:
Method VALIDATE_KEYS is closed for any modification:
* Achieve the same functionality (e.g. validating the object key) by creating a new class implementing LIF_SUBOBJ (e.g. LCL_WERKS for Plant validation)
* Add a new common functionality (e.g. saving data into Ztable) by creating a new method in the interface (e.g. method SAVE_DATA_TO_ZTAB in class LIF_SUBOBJ)

We need to follow the Design principle while developing the software to reduce the TCO (Total Cost of Ownership), Reduce the Cost of maintenance and for robust design.

 

Definition:
The name itself sounds like contradicting – OPEN & CLOSE, but by definition, A module should be OPEN for extension but CLOSED for modification. The Open-Closed Principle (OCP) is one of the most important Design Principle. OCP originated from the work of by the Bertrand Meyer.

 

In simple words: We can add new features in the module without changing the existing code (CLOSED) but by adding new code (OPEN).  By following this principle, we can make sure that by changing the code in the method we are not going to break existing functionality. Let us try to see it using the example.

 

Example:
First of all we would see the code which doesn’t follow this principle. Consider we have a class which prints the shape information of different shapes based on the input.
image

Code snippet which violates this principle.

 

Now the problem with this code is, when ever we need to add a new type of Shape, we need to change the code in the CREATE_SHAPE, WRITE_SHAPE method, which is clear violation of the OCP. According to OCP, we should only change the method to add new functionality. Here we are not adding a new functionality. Creation of the Shape Object and writing the information of the different Shape is not a new functionality. So, we must re-design our class and methods to be able to follow the Open Closed Principle.

 

We can use the dynamic polymorphism to achieve Open-Closed design. Check the UML for the new design.

image

Now we would create an interface LIF_SHAPE which we will use to create different shapes like circle using LCL_CIRCLE, square using LCL_SQUARE and so on.

 

Implementation of the class LCL_CIRCLE and LCL_SQUARE implements the method

 

Design of the report class is also changed. LCL_REPORT would now accept the class name instead of the simple type to instantiate required object as the parameter of the method CREATE_SHAPE.

 

Implementation of the class LCL_REPORT needs to be changed. CREATE_SHPAE would create the object and WRITE_SHAPE would call the method WRITE_SHAPE from the object O_SHAPE.

 

Full code Snippet which shows how to achieve OCP design.

 

Now, if we want to add a new shape, say TRIANGLE. We can easily add a new shape without changing any existing code.
1. Create a new class LCL_TRIANGLE which implements the interface LIF_SHAPE
2. Implement the method LIF_SHAPE~WRITE_SHAPE in this class.

 

Conclusion:
By using the polymorphism, now both methods CREATE_SHAPE & WRITE_SHAPE of the class LCL_REPORT are CLOSED for any modification and we have successfully achieved OCP design.


Credits:
Bertrand Meyer
Robert C. Martin