Dependence Inversion Principle 简称 DIP

抽象不应该依赖于细节,细节应该依赖于抽象

  1. 高层模块不应该依赖低层模块,两者都应该依赖其抽象.不可分割的原子逻辑就是低层模式,原子逻辑组装成的就是高层模块。
  2. 抽象不应该依赖细节。java 中,抽象 -> 接口或抽象类;细节 -> 实现类
  3. 细节应该依赖抽象

精简一下就是 「面向接口编程」 ,是面向对象设计的精髓之一,可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险, 在 java 中的表现:

  • 模块间依赖通过抽象(接口)发生,实现类之间不直接依赖
  • 接口或抽象类不依赖于实现类
  • 实现类依赖于接口或抽象类

这样的好处:解耦类和类之间的关系,不然你依赖另外一个类的话,另外一个类修改,你这里也要修改,
而如果依赖接口,那么需要修改的话,只要在实现类修改,依赖类不需要修改。

代码讲解

对于下面的代码:

  1. public class StringProcessor { //具体类
  2. private final StringReader stringReader; //具体类
  3. private final StringWriter stringWriter; //具体类
  4. //通过构造函数来注入依赖组件
  5. public StringProcessor(StringReader stringReader, StringWriter stringWriter) {
  6. this.stringReader = stringReader;
  7. this.stringWriter = stringWriter;
  8. }
  9. public void readAndWrite() {
  10. stringWriter.write(stringReader.getValue());
  11. }
  12. //测试用例
  13. public static void main(String[] args) {
  14. StringReader sr = new StringReader();
  15. sr.read("1111111");
  16. StringWriter sw = new StringWriter();
  17. StringProcessor sp = new StringProcessor(sr,sw);
  18. sp.readAndWrite();
  19. }
  20. }

优点就是逻辑简单,一眼就能看明白,但是耦合严重,这时,如果我们想要复用 StringProcessor 组件,则需要在引入的地方写很多重复代码。

  1. public interface StringProcessor {
  2. void readAndWrite(StringReader stringReader, StringWriter stringWriter);
  3. }
  4. public interface StringReader {
  5. void read(String path);
  6. String getValue();
  7. }
  8. public interface StringWriter {
  9. void write(String value);
  10. }
  11. public class StringProcessorImpl implements StringProcessor {
  12. //StringReader 是接口
  13. //StringWriter 是接口
  14. @Override
  15. public void readAndWrite(StringReader stringReader, StringWriter stringWriter) {
  16. stringWriter.write(stringReader.getValue());
  17. }
  18. public static void main(String[] args) {
  19. StringReader sr = new StringReaderImpl();
  20. sr.read("333333");
  21. StringWriter sw = new StringWriterImpl();
  22. StringProcessor sp = new StringProcessorImpl();
  23. sp.readAndWrite(sr,sw);
  24. }
  25. }

过去,StringProcessor 依赖于 StringReader 和 StringWriter 的具体实现,
而现在则是 StringProcessor 来定义一组抽象规则,由 StringReader 和 StringWriter 来依赖。