设计原则之依赖倒置原则
1.依赖倒置原则
1.1 定义
1).上层模块不应该依赖底层模块,它们都应该依赖于抽象。
2).抽象不应该依赖于细节,细节应该依赖于抽象。
3).顶层模块和底层模块都是一个抽象概念,一般我们也会将软件进行模块划分,比如业务层、逻辑层和数据层,业务层就是上层,数据层就是底层。随着模块的粒度划分不同这种上层与底层模块会进行变动,也许某一模块相对于另外一模块它是底层,但是相对于其他模块它又可能是上层。
4).抽象和细节,具体映射到软件开发中,抽象可以是接口或者抽象类形式,细节就是继承抽象的子类或者实现接口的接口实现类
1.2 UML类图
1.3 设计背景
在代码设计中,往往会出现顶层模块依赖底层模块情况出现,比如现在要用代码实现设计一个人出门的方式有骑自行车,开汽车,坐火车等方式,上述业务具体映射到代码中可分为Person模块,Bike模块,Car模块,Train模块。按照主次划分,Person 属于上层模块,Bike、Car 和 Train 属于底层模块。
/**
* @author tbb
* 自行车类
*/
public class Bike
{
public String run()
{
return "自行车";
}
}
/**
* @author tbb
* 汽车类
*/
public class Car
{
public String run()
{
return "汽车";
}
}
/**
* @author tbb
* 火车类
*/
public class Train
{
public String run()
{
return "火车";
}
}
public class Person
{
public void TravelMode()
{
Car car = new Car();
Bike bike = new Bike();
Train train = new Train();
//Person模块依赖Car模块,Bike模块,Train模块
System.out.println(car.run());
}
}
public class Test
{
public static void main(String[] args)
{
Person person = new Person();
person.TravelMode();//汽车
}
}
1.4 实现思路
要想解决代码设计中顶层模块依赖底层模块的情况,其实就是我们的依赖倒置原则,它引进了抽象。上层依赖于抽象,底层的实现细节也依赖于抽象,所以依赖倒置我们可以理解为依赖关系被改变,如果非常纠结于倒置这个词,那么倒置的其实是底层细节,原本它是被上层依赖,现在它倒要依赖与抽象的接口。
1.5 实现场景
/**
* @author tbb
* 自行车类
*/
public class Bike implements TravelTool
{
public String run()
{
return "自行车";
}
}
/**
* @author tbb
* 汽车类
*/
public class Car implements TravelTool
{
public String run()
{
return "汽车";
}
}
/**
* @author tbb
* 火车类
*/
public class Train implements TravelTool
{
public String run()
{
return "火车";
}
}
/**
* @author 26530
* 出行工具接口类
*/
public interface TravelTool
{
String run();
}
public class Person
{
private TravelTool travelTool;
public Person(TravelTool travelTool) {
super();
this.travelTool = travelTool;
}
public void TravelMode()
{
System.out.println(travelTool.run());
}
}
public class Test
{
public static void main(String[] args)
{
TravelTool travelTool = new Car();
Person person = new Person(travelTool);
person.TravelMode();//汽车
/*
在上面代码中,Person 把内部依赖的创建权力移交给了 Test 这个类中的 main() 方法。也就是说 Person 只关心依赖提供的功能,但并不关心依赖的创建。
这种思想其实就是 IoC,IoC 是一种新的设计模式,它对上层模块与底层模块进行了更进一步的解耦。控制反转的意思是反转了上层模块对于底层模块的依赖控制。
比如上面代码,Person 不再亲自创建 TravelTool 对象,它将依赖的实例化的权力交接给了 Test。而 Test 在 IoC 中又指代了 IoC 容器 这个概念
*/
}
}