一、依赖倒置原则定义
依赖倒置原则:抽象不应该依赖于实现,实现应该依赖于抽象,也就是说我们应该面对抽象(接口)编程,而不应该面对实现编程。
二、依赖倒置原则描述
依赖倒置原则要求我们在程序代码中传递参数或在关联关系时,尽量引用高层次类抽象类(接口类),而不应该引用具体的实现类,即使用抽象类或者接口进行变量类型声明、参数类型声明、方法返回结果声明。
在引用抽象层之后,系统将得到很好的灵活性,抽象类无需改变,只需新增新的实现类即可,也满足了开闭原则。
三、依赖倒置原则示例场景
现有一个抽奖策略的设计,在不使用设计模式时,设计了一个DrawControl
抽奖控制类,这个类里面包含了doDrawRandom()
、doDrawWeight()
两种抽奖策略,这种设计在实际开发起来速度是非常快的,但是后续不好维护,如果后续要新增其他的抽奖策略该类就要新增方法不利于维护也不满足开闭原则。
public class DrawControl {
public List<BetUser> doDrawRandom (List<BetUset> list, int count) {
// 随机抽取指定数量的用户,作为中奖用户
}
public List<BetUser> doDrawWeight (List<BetUset> list, int count) {
// 权重排名获取指定数量的用户,作为中奖用户
}
}
现进行重构满足依赖倒置原则,定义一个IDraw
抽奖接口,包含prize()
方法,新增两个抽奖的实现类DrawRandom
(随机抽取指定数量的用户,作为中奖用户)、DrawWeightRank
(权重排名获取指定数量的用户,作为中奖用户),DrawControl
抽奖控制类只定义一个doDraw()
方法,具体的抽象策略使用参数传入,而且参数传入高层的接口类,不参与具体的实现类。这样子就满足了灵活性,后续业务如果要新增抽奖策略新增新的实现类即可,DrawControl
类可以不用改变,满足了依赖倒置原则,同时也满足了开闭原则。
public interface IDraw {
List<BetUser> prize(List<BetUser> list, int count);
}
public class DrawRandom implements IDraw {
@Override
public List<BetUser> prize(List<BetUser> list, int count) {
// 随机抽取指定数量的用户,作为中奖用户
}
}
public class DrawWeightRank implements IDraw {
@Override
public List<BetUser> prize(List<BetUser> list, int count) {
// 权重排名获取指定数量的用户,作为中奖用户
}
}
public class DrawControl {
// 也可以用注入的方式
private IDraw draw;
public List<BetUser> doDraw(IDraw draw, List<BetUser> betUserList, int count) {
return draw.prize(betUserList, count);
}
}