open-closed-principlesolid-principles

How to respect Open closed principle when you have business logic change?


We are doing some big changes in our system and I'd like to know the best way to implement these new business logic rules, respecting SOLID principles :

Open / Closed principles says "Open for extension, but close for modification" ok, but how can I do modification ? I mean, I don't want to keep the old business logic, and in my mind "extension" mainly means "adding code" not "changing code" , so what did I understood wrong ?


Solution

  • Two big questions:

    What kind of changes are we talking we about here?

    What kind of existing code do you have? Is it already conforming to any SOLID principles?

    Let's suppose we need to make some changes to a well-designed existing application. Consider perhaps a payroll application. We might have an Interafce (this is just a contrived example)

     public Interface EmployeeContract {         
          public int computeSalaryForMonth(int month);
     }
    

    and we have implementations:

     public class SalesContract implements EmployeeContract {
          public int computeSalaryForMonth(int month){
                   // computation involving sales figures and base salary
          }
     }
    
      public class HourlyContract implements EmployeeContract {
          public int computeSalaryForMonth(int month){
                   // computation involving hours worked and overtime payments
          }
     }
    

    Now all the other parts of the application are coded in terms of the Interface.

    We can now add new kinds of contract without changing any existing code, we are open for extension and adding possibly quite complex new business logic.

    BUT that's because the original designer anticipated that kind of change, adding new monthly contract types. Not so good if we wanted to take on employees who are paid weekly? Now our interface is not suitable, we need to change it, and the effects will ripple through other code.

    Realistically, software will not be open to painless change of arbitrary business logic, and indeed trying to be flexible up front can absorb lots of effort. However do notice that even though in my example the Interface is not quite as flexible as we now need, because the Interface is the coupling point it's vey easy to identify the portions of the code that need to be changed.

    Summary: in your situation:

    1. Understand the structure of the existing code and where it has points of flexibility. Accept that some code will need to change, and that it's unsurprising that significnat changes in the business may require significant changes in the code.
    2. Structure generally helps with maintainability, so as you add new code pay attention to structure. Provide "firewalls" in your code by coding to Interfaces, striking a balance between getting the job done and being open to extension.