Click here to Skip to main content
Click here to Skip to main content

Dependency Inversion principle (DIP)

By , 23 Jul 2012
 

SOLID principles:

Depend explicitly, require explicitly, but only require what you really need.

Consider an example (not for production, illustrative purposes only):

public class ConsoleLogger {
  public static void log(String text)  {...}
}

public class SomethingDoer {
  public void doSomething() {
    // I won't show you the code      
  }
}

Is there a connection between SomethingDoer and Logger? You'll never know unless you have a code for SomethingDoer. OK, I'll show you:

public class SomethingDoer {
  public void doSomething() {
    ConsoleLogger.log(new Date().toString());
  }
}

This may not look that bad as long as you have the code. But what if this SomethingDoer is in a 3rd-party library and it sends some stuff to the console while you don't want it? The solution is to explicitly say: "SomethingDoer depends on Logger". Here is a possible solution:

public class ConsoleLogger {
  public void log(String text)  {...}
}

public class SomethingDoer {
  private final ConsoleLogger logger;

  public SomethingDoer(ConsoleLogger logger) {
    this.logger = logger;
  }

  public void doSomething() {
    logger.log(new Date().toString());
  }
}

Logger logger = new Logger();
SomethingDoer somethingDoer = new SomethingDoer(logger);

In this code, you just can't make an instance of SomethingDoer without giving it an instance of Logger. But still, what should we do in case we don't want any output at all? SomethingDoer doesn't basically require any particular logger, it requires something that IS a logger, but no further details are required. So, here's the next step:

public interface Logger {
  void log(String text);
}

public class ConsoleLogger implements Logger {
  public void log(String text) {...}
}

public class NullLogger implements Logger {
  public void log(String text) { /* do nothing here */ }
}

public class SomethingDoer {
  private final Logger logger;

  public SomethingDoer(Logger logger) {
    this.logger = logger;
  }

  public void doSomething() {
    logger.log(new Date().toString());
  }
}

// if we want to enable output:
Logger logger = new ConsoleLogger();
SomethingDoer somethingDoer = new SomethingDoer(logger);
somethingDoer.doSomething(); // got output

// if we want to disable output:
Logger logger = new NullLogger();
SomethingDoer somethingDoer = new SomethingDoer(logger);
somethingDoer.doSomething(); // no output

In next posts I'm going to cover this topic in more details.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

loki2302
Software Developer (Senior)
Russian Federation Russian Federation
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 23 Jul 2012
Article Copyright 2012 by loki2302
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid