在传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块;抽象层次依赖于具体层次。倒转原则就是要把这个错误的依赖关系倒转过来。
依赖(或耦合)关系的分类:
零耦合关系:如果两个类没有耦合关系,就称之为零耦合
具体耦合关系:具体耦合关系发生在两个具体的(可实例化)的类之间,经由一个类对另一个类的直接引用造成。
抽象耦合关系:抽象耦合关系发生在一个具体类和一个抽象类(或者java接口)之间,使两个发生关系的类之间存有最大的灵活性。
依赖倒转原则:要依赖于抽象,不要依赖于具体;抽象不应该依赖于细节,细节应该依赖于抽象(abstractions should not depend upon details,details should depend upon abstractions);不要针对接口编程,要依赖于实现编程(program to an interface,not an implementation)
针对接口编程的意思是说,应当使用java接口和抽象java类进行变量的类型声明、参量的类型声明、方法的返还类型声明、以及数据类型的转换等。
不要针对实现编程的意思是,不应当使用具体的java类进行变量的类型声明、参量的类型声明 、方法的返还类型声明、以及数据类型的转换等。
变量被声明时的类型叫做变量的静态类型(明显类型),变量所引用的对象的真实类型叫做变量的真实类型。例如
List list = new ArrayList(); list变量的静态类型是List,真实类型是ArrayList。
在很多情况下,一个java程序需要引用一个对象。这个时候,如果这个对象有一个抽象类型的话,应当使用这个抽象类型作为变量的静态类型。这就是针对接口编程的含义。
在创建一个对象时,java语言要求使用new关键字以及这个类本身。而一旦这个对象被创建出来,那么就可以灵活的使用这个对象的抽象类型来引用它。因此,java语言中创建一个对象的过程是违背“开-闭”原则以及依赖倒转原则的。虽然在这个类被创建出来之后,可以通过多态性使得客户端依赖于其抽象类型。
在设计模式中的体现:
工厂方法模式:该模式将创建一个类的实例的过程封装起来,消费这个实例的客户端仅仅得到实例化的结果,以及这个实例的抽象类型。简单工厂模式将违反“开-闭”原则以及依赖倒转原则的做法封装到了一个类里面,而工厂方法模式将这个违反原则的做法推迟到了具体工程角色中。