views:

46

answers:

3

Hi All,

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 ?

A: 

Open-closed principles means that you don't have to change your present code so it's CLOSED for modification but to fulfil new requirements your need to extend the code using subclasses, implementing interfaces, desing patterns so that your code is OPEN for this activities. of cause while refactoring you will face that you need to CHANGE code but you have to do it a way to saticfy OSP.

for instance instead of creting new instaces of similar object scattered around the code you may to create a Factory Method. When new requiremet comes to add one new object your code will be CLOSED for modification (no new instances in the code) but OPEN for modification (extend Factory Method).

Arseny
+1  A: 

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.
djna
The kind of changes you're talking about is these (tourism industry) :In the past the owner could say "a week in June is 20€", now he can say "a week in June is 20€ but if you want to stay 8 days it's 5€ per bonus day". Thank you for your enlightening, I think it's good to see these principles as guide-line and not as must-do.
remi bourgarel
+2  A: 

The idea behind Open/Closed is that if you need different business logic, you'll need to create a new business-logic class.

However, the primary motivation for this is that you don't want to impact existing code that's out there, retest, get signoff again, etc. If the business logic you're using has fundamentally changed, and you would be changing all references to a new object and obsoleting the old one, it would be acceptable in this case to re-open the object to modification. The key being (1) you're going to need to retest all the code anyway, and (2) the old object would not be used anywhere.

HTH, James

James B