6大设计原则之依赖倒置原则(Dependence Inversion Principle)。

本文详细阐述了依赖倒置原则的定义与应用,包括其实现方式、最佳实践及如何通过接口编程来降低类间的耦合度,提升代码的稳定性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
  • 抽象不应该依赖细节;
  • 细节应该依赖抽象。

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

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

更加精简的定义就是“面向接口编程”——OOD(Object-Oriented Design,面向对象设计)的精髓之一。

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

注意:设计是否具备稳定性,只要适当地“松松土”,观察“设计的蓝图”是否还可以茁壮地成长就可以得出结论,稳定性较高的设计,在周围环境频繁变化的时候,依然可以做到“我自岿然不动”。

司机接口(接口只是一个抽象化的概念,是对一类事物的最抽象描述)

public interface IDriver {

  // 是司机就应该会驾驶汽车

  public void drive(ICar car);

}

司机类的实现

public class Driver implements IDriver {

  // 司机的主要职责就是驾驶汽车

  public void drive(ICar car) {

   car.run();

  }

}

汽车接口

public interface ICar {

  // 是汽车就应该能跑

  public void run();

}

奔驰汽车类(宝马汽车类似,故省略)

public class Benz 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);

  }

}

注意:在Java中,只要定义变量就必然要有类型,一个变量可以有两种类型:表面类型和实际类型,表面类型是在定义的时候赋予的类型,实际类型是对象的类型,如zhangSan表面类型是IDriver,实际类型是Driver。

TDD(Test-Driven Development,测试驱动开发)就是依赖倒置原则的最高级应用。JMock工具,其最基本的功能是根据抽象虚拟一个对象进行测试。

测试类

public class DriverTest extends TestCase {

  Mockery context = new Junit4Mockery();

  @Test

  public void testDriver() {

    // 根据接口虚拟一个对象

    final ICar car = context.mock(ICar.class);

    IDriver driver = new Driver();

    // 内部类

    context.checking(new Exception(){{

        oneOf  (car).run();

    }});

    driver.drive(car);

  }

}

注意粗体部分,我们只需要一个ICar的接口,就可以对Driver类进行单元测试。从这一点来看,两个相互依赖的对象可以分别进行开发,孤立地进行单元测试,进而保证并行开发的效率和质量,TDD开发的精髓不就在这里吗?测试驱动开发,先写好单元测试类,然后再写实现类,这对提高代码的质量有非常大的帮助,特别适合研发类项目或在项目成员整体水平比较低的情况下采用。

对象的依赖关系有三种方式来传递:

  1. 构造函数传递依赖对象
  2. Setter方法传递依赖对象
  3. 接口声明依赖对象

最佳实践:

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。

  • 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备;
  • 变量的表面类型尽量是接口或者是抽象类(比如工具类就一般不需要接口或者抽象类)。
  • 任何类都不应该从具体类派生
  • 尽量不要覆写基类的方法
  • 结合里氏替换原则使用

通俗的规则:接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当地时候对父类进行细化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值