oopif-statementduck-typingliskov-substitution-principleopen-closed-principle

How to avoid if..else(or any conditionals) while deciding which method to be called?


How to follow Open Close Principle without violating LSP while deciding which method to be invoked with different parameters in a statically typed language?

Consider the requirement like

Code for above requirement would look like

process(obj) {
    
    if(obj.type === action1) {
       db.updateTable1()
    }
    if(obj.type === action2) {
       db.updateTable2(obj.status)
    }
    if(obj.type === action3) {
       //May be log action 3 recieved
    }
}

Figured out a way to follow OCP in above code for additional actions, by moving body of if statement to method and maintain a map of keys with action as name. Reference

However feels solution is violating the OCP as method wrapping the contents of first if block will not receive any parameter, second method wrapping the contents of second if block will have a parameter.

Either it forces all method to follow the same signature in trade off following OCP but violating LSP or give up OCP itself and thereby live with multi if statements.


Solution

  • The nature of obj is ambiguous, but I would recommend having a well-defined interface and pass it throughout your code where the class implementation of your interface would be equivalent to your 'action'. Here's an example of what that might look like in Typescript:

    interface someDBInterface {
      performAction() : void;
    }
    
    function process(obj : someDBInterface) {
      let result = obj.performAction();
    }
    
    class action1 implements someDBInterface {
      status: any
      performAction() {
        //db.updateTable1();
      }
    }
    
    class action2 implements someDBInterface {
      status : any
      performAction() {
        //db.updateTable1(this.status);
      }
    }
    
    class action3 implements someDBInterface {
      performAction() {
        //May be log action 3 recieved
      }
    }
    

    If this doesn't meet your requirements, feel free to reach out :)