In the previous post of the series Object Oriented Design Principles, we have seen:
1) Object Oriented Design Principles (OODP): Open-Closed Principle(OCP)
2) Object Oriented Design Principles (OODP): OCP with Business Scenario
By Definition, Dependency Inversion Principle (DIP) is: Depend upon Abstractions. Do not depend upon concretions.
Problem with the Procedural design:
Procedural designs exhibit always particular type of dependency. In the procedural programming, there would be always some code blocks which are repetitive. Like in the example, we have a program which has different set of the interfaces like interface to create Sales Order (as shown in the blog post: Object Oriented Design Principles (OODP): OCP with Business Scenario), Purchase Order etc. Program structure have some CONCRETE code blocks which makes it very RIGID. As shown in this diagram, we can’t use the Validation of the sub objects in more than one interface because it is wrapped in the concrete code block or FM.
Concrete classes are rigid, where as using interfaces make the design flexible. So, if we follow the object oriented design using proper abstraction we can remove the rigidity of the code and make our code blocks more reusable. Moreover, we can extend the abstract classes or interfaces to have new functionality and we can achieve the Open Closed Principle (OCP).
Every dependency should depend on the Interface or Abstraction class. There should be no dependency targeted on the concrete classes. For example, we would try to work on the object reference created with reference to abstract class or interface. We should try to define the method parameters, attributes with reference to abstract class or interface. There should not be direct reference of the concrete class.
We will try to explore the same example, as we have seen in the previous post Object Oriented Design Principles (OODP): OCP with Business Scenario. Method VALIDATE_KEYS of the class LCL_SO is not reusable. We can’t use that method in another object to achieve the same functionality, unless we instantiate the SO object and call the method. This makes the design little bit rigid. Let’s see how we can overcome this problem by following DIP.
Let’s check the UML diagram for this design:
To achieve the DIP in the same example, we can create an abstract class ZCL_AB_ORDER which contains all the common functionality e.g. VALIDATE method & common attributes e.g. table for sub-objects T_SUBOBJ. Based on this abstract class, we can inherit all main classes e.g. class for sales order ZCL_SALES_ORDER, class for purchase order ZCL_PURCHASE_ORDER etc. The attribute T_SUBOBJ will hold the object reference of the sub-objects like Material, Customer, Vendor etc.
Subclasses of the abstract class ZCL_AB_ORDER
For the sub-objects, we can create an interface ZIF_SUBOBJ which contains method definitions for common methods for the sub-objects like method VALIDATE_KEY. Use this interface in all the sub-objects like Material ZCL_MATERIAL, customer ZCL_CUSTOMER, Vendor ZCL_VENDOR etc. We can implement object specific validation in the inherited method from the ZIF_SUBOBJ e.g. material number validation against material master (table MARA) etc.
Subclasses of subobject interface ZIF_SUBOBJ:
We can create a utility class ZCL_UTILITIES which has some generic methods e.g. VALIDATION. This method can accept any object inherited from the abstract class ZCL_AB_ORDER. We can check all the sub-objects’ method VALIDATE_KEY to call the object specific validation.
Implementation of Method VALIDATION:
We call this method VALIDATION from the method VALIDATE of the abstract class ZCL_AB_ORDER. Since the parameter of the VALIDATION method depend on the abstract class ZCL_AB_ORDER, we can use this method with any object reference which is inherited from the abstract class ZCL_AB_ORDER. As a input of the method ZCL_UTILITES=>VALIDATION we are passing the current object (ME).
You can find the class design, implementation and test report in WIKI Object-Oriented Design Principle – Dependency Inversion Principle Example
* Abstraction would help us to create more reusable methods like VALIDATE in class ZCL_AB_ORDER and VALIDATION in class ZCL_UTILITIES.
* Code would lose the rigidity and become more flexible, which would lead to easy maintenance.
* We achieved DIP – Removed the dependency on the actual concrete class.
Robert C. Martin