Reducing Code Dependancy between layers/classes

The concept of programing to an interface or to an abstration is well known and understood. But when it comes to actual implementation lot of mistakes are made. Here I will try to show an example of how “The Dependency Inversion Principle” as suggested by Robert C. Martin.

Basically it helps reduce 3 things i.e. RFI (Rigidity, Fragility, and Immobility) of your code.

Robert C. Martin states that the three defining factors of “bad code” are:

  1. It is hard to change because every change affects too many other parts of the system (Rigidity)
  2. When you make a change, unexpected parts of the system break (Fragility)
  3. It is hard to reuse in another application because it cannot be disentangled from the current application (Immobility)

How do you fix these problems:

1. Any high level or low level component should be dependent on abstraction and not concrete implementations.

2. Abstractions should not depend upon details of your implementation. Interface or an abstraction should cater to the common functionality of your business logic and the lower level modules.

Example:

package example;

public class Account{

    SavingsAccount savingsAccount= new SavingsAccount();

    public void newAccount(Customer customer) {
        SavingsAccount.create(customer);
    }

    class SavingsAccount{
        public void create(Customer customer) {
            //TODO: your implementation 

        }
    }

}

In this example, the Account class is directly dependent on SavingsAccount, which has no abstractions and is the implementing class.

A better way of writing the same code would be:

1. Create an interface Account.

package example;

public interface IAccount{

    public void create(Customer customer) ;

}

2. Implement IAccount:

package example;

public class SavingsAccount implements IAccount{.
public void create(Customer customer) {
            //TODO: your implementation 

        }   
}

3. Implement Account:

package example;

public class Account{

    IAccount account= null;

    public void setAccountType(IAccount account) {
        this.account= account;
    }

    public void newAccount(Customer customer) {
        account.create(customer);
    }

}

As we can see, we have decoupled the invocation from the actual implementation that is your business logic.  Any changes in your acount type class wil not affect the implementation whioch could be a third party.so you are now not breaking the high level code. According to the rules of DIP, this is all we need in order to get rid of RFI in the code.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s