What is the "Principle of Dependency Inversion" (DIP)?

19

I am now familiar with the SOLID principle:

  • S Single Responsabilty Principle
  • O Open / Closed
  • L Liskov Substitution Principle
  • I Interface Segregation
  • D Dependency Inversion Principle

However, I could not understand the last of the Principle of Dependency Inversion! What is it and when should I use it? I would like a simple Java language example of its use.

    
asked by anonymous 02.12.2015 / 16:58

2 answers

12

What is Dependency Inversion Principle ?

The Dependency Inversion Principle seeks to maintain the focus of the design task on the business, leaving this design independent or uncoupled from the component that will perform the low-level tasks that are not part of the modeling of the business.

In respect of this principle, instead of developing the low-level component and from there guiding the development of the high-level component, you define how the interaction between these components will be (always giving priority to the design needs of the component high-level component), and hence the low level component has to be developed respecting this definition of interaction with the high level component.

Example - stock exchange quotes

Let's say you need to develop a screen that shows the user, a trader on the stock exchange, the current quote of each asset that he holds in his portfolio.

The operator wants the screen to be updated every time an asset's price changes, because it wants to know the total per asset and total in the portfolio almost in real time.

The operator will pay for a real-time web quote service and your software must use this service.

You need to make a component that connects to this service, and the service will notify your component every time a role changes its value, and then the component can update the portfolio by promoting the screen update.

The simplest way to develop this software would be to first implement the component that connects to the service (called here ConnectorBolsa ), see how it stayed and then implement the portfolio update according to the needs of ConnectorBolsa :

Inthesolutionabove,thehighlevelcomponentdependsonthelowlevelcomponent.

ThewaytodothisrespectingtheDependencyInversionPrinciplewouldbetodefinehowtheinteractionbetweenthecomponentsshouldbe,andthenbothcomponentsaredevelopedrespectingthisdefinitionofinteractionbetweenthem.

This"definition of interaction" is called "abstraction". We say that you have created an abstraction between components .

Eachcomponentdoesnotneedtoknowhowtheotherwasimplemented,andthefocusofthedesignisonthebusinesssolutionandnotonthedetailsofhowtheconnectiontothequoteserviceismade.

Interfaces

ThemostcommonwaytodothisinJavaisbydeclaringaninterfacethatdetermineshowtheportfolioupdatecomponentwouldliketoconsumeaquoteservice,andthenthecomponentthatconnectstothequoteserviceimplementsthisinterface.

Before, the high-level component depended on the low-level component but now, with the above solution, the low-level component depends on an interface defined by the business guidelines - we say then that there was a inversion .

Ability to replace the component in the future?

This is the meanest motive for respecting the principle.

The major benefit of the principle is to keep the design focus on business needs rather than relying on the implementation details and needs of the lower-level objects.

Respect for the principle should also result in more reusable components that do not need to change just to keep up with the changes needed in another component (components can change independently of one another).

Finally, a very positive side effect of the business component no longer being coupled to the low-level component is that the low-level component can be replaced by a stunt (mock) during automated testing.

    
02.12.2015 / 22:20
2

We can consider low-level classes the classes that implement the basic and primary operations (disk access, network protocols) and high-level classes (business flows).

A natural way to implement such structures would be to write the low-level classes and once you have written them you will begin to write the high-level classes. As high-level classes are defined in other terms this seems to be the most logical way

But this is not a flexible design. What happens if I need to replace a low-level class? Would you have to rewrite your entire high-level class? One is dependent on the other, for this reason the DIP was created.

As you can see from the example, thus reformulating the concept of this dependency:

interface IWorker 
{
  public void work();
}
class Worker implements IWorker
{
  public void work() 
  {
    // ....working
  }
}
class SuperWorker  implements IWorker
{
   public void work() 
   {
    //.... working much more
   }
}
class Manager 
{
   IWorker worker;

   public void setWorker(IWorker w) 
   {
      worker = w;
   }

  public void manage() 
  {
    worker.work();
  }
}

I would suggest the link: DIP - Example

    
02.12.2015 / 17:58