依赖倒置原则
依赖倒置原则(Dependence Inversion Principle),简称DIP。
定义
High level modules should depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
即
1、高层模块不应该依赖低层模块,两者都应该依赖于抽象(抽象类或接口)
2、抽象(抽象类或接口)不应该依赖于细节(具体实现类)
3、细节(具体实现类)应该依赖抽象
抽象:即抽象类或接口,两者是不能够实例化的。
细节:即具体的实现类,实现接口或者继承抽象类所产生的类,两者可以通过关键字new直接被实例化。
而依赖倒置原则的本质骑士就是通过抽象(抽象类或接口)使各个类或模块的实现彼此独立,不相互影响,实现模块间的松耦合。但是这个原则也是6个设计原则中最难以实现的了,如果没有实现这个原则,那么也就意味着开闭原则(对扩展开发,对修改关闭)也无法实现。
依赖倒置有三种方式来实现
1、通过构造函数传递依赖对象
比如在构造函数中的需要传递的参数是抽象类或接口的方式实现。
2、通过setter方法传递依赖对象
即在我们设置的setXXX方法中的参数为抽象类或接口,来实现传递依赖对象
3、接口声明实现依赖对象
例如下面的例子:
public class zx {
//zx会煮面
public void cook(Noodles noodles)
{
noodles.eat();
}
}
面条类(目前只会煮面)
public class Noodles {
//吃面条
public void eat()
{
System.out.println("zx吃面条");
}
}
场景类
public class Home {
public static void main(String args[])
{
Zx zx = new Zx();
Noodles food = new Noodles();
zx.cook(food);
}
}
运行结果:zx吃面条
但是这有个问题,zx只会做面条,但不可能每次都吃面条。所以需要学会其他的。
也就是zx通过学习还可以做米饭等其他的。
public interface IZx {
//这样就会做很多饭菜了
public void cook(IFood food);
}
实现类
public class Zximplements IZx {
@Override
public void cook(IFood food) {
food.eat();
}
}
食物接口
public interface IFood {
public void eat();
}
这样就为扩展留出了很大的空间,方面扩展其他的类。也不会对细节有变动。
实现面条
public class Noodles implements IFood {
@Override
public void eat() {
System.out.println("zx吃面条");
}
}
实现米饭
public class Rice implements IFood {
@Override
public void eat() {
System.out.println("zx吃米饭");
}
}
场景类
public class Home {
public static void main(String args[])
{
Zx zx = new zx();
//实例化米
IFood rice = new Rice();
//吃面条
//IFood noodles = new Noodles();
zx.cook(rice);
}
}
这样各个类或模块的实现彼此独立,不互相影响,实现了。