设计模式—— 三:依赖倒置原则

简介: 设计模式—— 三:依赖倒置原则

文章目录

什么是依赖倒置原则?

先看看依赖倒置原则的原始定义:

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions

翻译一下,包含三层定义:

● 高层模块不应该依赖低层模块,两者都应该依赖其抽象;

● 抽象不应该依赖细节;

● 细节应该依赖抽象。

高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。

抽象和细节呢?在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化。

依赖倒置原则在Java语言中的表现就是:

● 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过 接口或抽象类产生的;

● 接口或抽象类不依赖于实现类;

● 实现类依赖接口或抽象类。

为什么要用依赖倒置原则?

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

以司机驾驶奔驰车为例:

3-1:司机驾驶奔驰车类图

image.png

奔驰车提供一个方法run,代表车辆运行。

奔驰车类:

public class Benz { 
 //汽车会跑 
  public void run(){ 
    System.out.println("奔驰汽车开始运行..."); 
   }
}

司机通过调用奔驰车的run方法开动奔驰车.

司机类:

public class Driver { 
  //司机的主要职责就是驾驶汽车
   public void drive(Benz benz){ 
   benz.run();
   }
 }

有车,有司机,在Client场景类产生相应的对象.

场景类:

public class Client { 
  public static void main(String[] args) { 
    Driver zhangSan = new Driver();
    Benz benz = new Benz(); //张三开奔驰车 
    zhangSan.drive(benz);
   } 
 }

以上实现了司机开车的场景,在功能上是没有问题。

现在新的需求来了,司机不仅要开奔驰车,还要开宝马车。

宝马车类:

public class BMW { 
  //宝马车当然也可以开动了
   public void run(){ 
     System.out.println("宝马汽车开始运行..."); 
    }
 }

现在发现问题了,司机没有开动宝马车类的方法,怎么办?给司机类添加开宝马车的方法吗?如果接下来司机要开挖掘机呢?在这里,司机类和奔驰车类之间是紧耦合的关系,其导致的结果就是系统的可维护性大大降低。

这时候就应该引入依赖倒置原则。

3-2:引入依赖倒置原则后的类图

image.png

建立两个接口:IDriver和ICar,分别定义了司机和汽车的各个职能,司机实现现drive()方法。

司机接口:

public interface IDriver { 
 //老司机,会开车
  public void drive(ICar car); 
}

司机实现类:实现IDriver接口:

public class Driver implements IDriver{
  //司机的主要职责就是驾驶汽车 
  public void drive(ICar car){
     car.run();
 } 
}

在IDriver中,通过传入ICar接口实现了抽象之间的依赖关系,Driver实现类也传入了ICar 接口,至于到底是哪个型号的Car,需要在高层模块中声明。

汽车接口及两个实现类:

public interface ICar { 
 public void run();
 }
//奔驰汽车类
public class Benz implements ICar{ 
  public void run(){ 
  System.out.println("奔驰汽车开始运行...");
 } 
}
//宝马汽车类
public class BMW implements ICar{ 
  public void run(){ 
    System.out.println("宝马汽车开始运行...");
  } 
}

业务场景类:

public class Client { 
  public static void main(String[] args) { 
    IDriver zhangSan = new Driver(); 
    ICar benz = new Benz();
    //张三开奔驰车
     zhangSan.drive(benz); 
    ICar bmw = new BMW(); 
    //张三开宝马车
    zhangSan.drive(bmw);
   } 
}

在新增加低层模块时,只修改了业务场景类,也就是高层模块,对其他低层模块如 Driver类不需要做任何修改,业务就可以运行,把“变更”引起的风险扩散降到最低。

依赖的三种写法

依赖是可以传递的,A对象依赖B对象,B又依赖C,C又依赖D——只要做到抽象依赖,即使是多层的依赖传递也是没有丝毫问题的。

对象的依赖关系有三种方式来传递,如下所示:

1.构造函数传递依赖对象

在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入,按照这种方式的注入,对IDriver和Driver进行修改。

public interface IDriver { 
  //司机就会开车
   public void drive(); 
}
public class Driver implements IDriver{
  private ICar car; 
  //构造函数注入 
  public Driver(ICar _car){ 
    this.car = _car; 
  }
  //司机的主要职责就是驾驶汽车 
  public void drive(){ 
    this.car.run(); 
  } 
}

2、Setter方法传递依赖对象

在抽象中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入,按照这种方式的注入,对IDriver和Driver进行修改:

public interface IDriver { 
  //车辆型号 
  public void setCar(ICar car);
 //是司机就应该会驾驶汽车
  public void drive(); 
}
public class Driver implements IDriver{
  private ICar car; 
  public void setCar(ICar car){ 
  this.car = car; 
  }
 //司机的主要职责就是驾驶汽车
 public void drive(){ 
   this.car.run();
  } 
}

3、接口声明依赖对象

在接口的方法中声明依赖对象,未修改的IDriver和Driver就采用了接口声明依赖的方式,该方法也叫做接口注入。

public interface IDriver { 
 //老司机,会开车
  public void drive(ICar car); 
}
public class Driver implements IDriver{
   //司机的主要职责就是驾驶汽车 
   public void drive(ICar car){ 
     car.run(); 
   } 
}



目录
相关文章
|
5月前
|
设计模式
设计模式六大原则之依赖倒置原则
设计模式六大原则之依赖倒置原则
|
6月前
|
设计模式 Java
Java设计模式七大原则之依赖倒置原则
Java设计模式七大原则之依赖倒置原则
65 0
|
设计模式 uml
设计模式-浅谈依赖倒置原则
设计模式-浅谈依赖倒置原则
|
设计模式 Java Spring
【设计模式】依赖倒置原则与工厂方法模式与spring
【设计模式】依赖倒置原则与工厂方法模式与spring
115 0
|
设计模式 测试技术
设计模式 - 六大设计原则之DIP(依赖倒置原则)
设计代码架构时,高层模块不应该依赖于底层模块,二者都应该依赖于抽象。 抽象不应该依赖于细节,细节应该依赖于抽象。 依赖倒置原则是实现开闭原则的重要途径之一, 它降低了类之间的耦合,提高了系统的稳定性和可维护性。
142 0
设计模式 - 六大设计原则之DIP(依赖倒置原则)
|
设计模式
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(三)
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(三)
112 0
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(三)
|
设计模式 Java uml
设计模式六大原则(三)----依赖倒置原则
设计模式六大原则(三)----依赖倒置原则
138 0
|
存储 设计模式 数据库
大话设计模式--第五章 依赖倒置原则
依赖倒置原则: 原话解释的是, 抽象不应该依赖于细节, 细节应该依赖于抽象. 说白了, 就是上面那句话。针对接口编程, 不要针对实现编程。
98 0
|
设计模式
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(二)
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(二)
129 0
|
设计模式
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(一)
【设计模式】软件设计七大原则 ( 依赖倒置原则 | 代码示例 )(一)
120 0