Dependence Inversion Principle 简称 DIP
抽象不应该依赖于细节,细节应该依赖于抽象
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象.不可分割的原子逻辑就是低层模式,原子逻辑组装成的就是高层模块。
- 抽象不应该依赖细节。java 中,抽象 -> 接口或抽象类;细节 -> 实现类
- 细节应该依赖抽象
精简一下就是 「面向接口编程」 ,是面向对象设计的精髓之一,可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险, 在 java 中的表现:
- 模块间依赖通过抽象(接口)发生,实现类之间不直接依赖
- 接口或抽象类不依赖于实现类
- 实现类依赖于接口或抽象类
这样的好处:解耦类和类之间的关系,不然你依赖另外一个类的话,另外一个类修改,你这里也要修改,
而如果依赖接口,那么需要修改的话,只要在实现类修改,依赖类不需要修改。
代码讲解
对于下面的代码:
public class StringProcessor { //具体类private final StringReader stringReader; //具体类private final StringWriter stringWriter; //具体类//通过构造函数来注入依赖组件public StringProcessor(StringReader stringReader, StringWriter stringWriter) {this.stringReader = stringReader;this.stringWriter = stringWriter;}public void readAndWrite() {stringWriter.write(stringReader.getValue());}//测试用例public static void main(String[] args) {StringReader sr = new StringReader();sr.read("1111111");StringWriter sw = new StringWriter();StringProcessor sp = new StringProcessor(sr,sw);sp.readAndWrite();}}
优点就是逻辑简单,一眼就能看明白,但是耦合严重,这时,如果我们想要复用 StringProcessor 组件,则需要在引入的地方写很多重复代码。
public interface StringProcessor {void readAndWrite(StringReader stringReader, StringWriter stringWriter);}public interface StringReader {void read(String path);String getValue();}public interface StringWriter {void write(String value);}public class StringProcessorImpl implements StringProcessor {//StringReader 是接口//StringWriter 是接口@Overridepublic void readAndWrite(StringReader stringReader, StringWriter stringWriter) {stringWriter.write(stringReader.getValue());}public static void main(String[] args) {StringReader sr = new StringReaderImpl();sr.read("333333");StringWriter sw = new StringWriterImpl();StringProcessor sp = new StringProcessorImpl();sp.readAndWrite(sr,sw);}}
过去,StringProcessor 依赖于 StringReader 和 StringWriter 的具体实现,
而现在则是 StringProcessor 来定义一组抽象规则,由 StringReader 和 StringWriter 来依赖。
