返回

探索依赖倒置原则(DIP):将抽象与具体分开

见解分享

SOLID 原则中的依赖倒置原则(DIP)

在探索依赖倒置原则(Dependency Inversion Principle,简称 DIP)之前,我们先回顾一下上两期内容中讨论过的 SOLID 原则:

  • 单一职责原则(Single Responsibility Principle,简称 SRP):一个类或模块只应负责一项职责。
  • 开闭原则(Open/Closed Principle,简称 OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

DIP 是 SOLID 原则的第五个也是最后一个原则。它规定,高级模块不应该依赖具象的低级模块,它们都应该依赖抽象。抽象不应该依赖具体,具体应该依赖抽象。

理解 DIP 的关键点

  • 抽象: DIP 中的抽象是指不会改变的接口或类。它定义了行为或功能,但不会实现它们。抽象是通用的,可以被许多不同的具体类实现。
  • 具体: DIP 中的具体是指实现了抽象接口或类的类。它是特定的,只能用于一种目的。具体类依赖于抽象类,而抽象类不依赖于具体类。

DIP 的优点

DIP 有许多优点,包括:

  • 灵活性: DIP 使得代码更具灵活性。当您需要更改具体类时,您不必更改高级模块。您只需更改具体类并重新编译代码。
  • 可维护性: DIP 使得代码更容易维护。当您需要修复错误或添加新功能时,您只需要更改受影响的具体类。您不必担心更改高级模块。
  • 可测试性: DIP 使得代码更容易测试。您可以独立测试具体类,而无需测试高级模块。

如何使用 DIP

您可以通过以下步骤使用 DIP:

  1. 首先,您需要定义一个抽象接口或类。这个接口或类应该定义您需要的高级模块的行为或功能。
  2. 接下来,您需要实现抽象接口或类。这些具体类应该实现抽象接口或类定义的行为或功能。
  3. 最后,您需要在高级模块中使用抽象接口或类。这样,您就可以使用具体类而无需担心具体类的实现细节。

DIP 的示例

为了更好地理解 DIP,让我们来看一个示例。假设您有一个绘图应用程序。这个应用程序允许用户绘制各种形状,如线条、矩形和圆形。

在没有使用 DIP 的情况下,您可能会创建一个名为 Shape 的类来表示形状。这个类将包含所有形状的通用属性和方法。您还可能会创建一个名为 Drawing 的类来表示绘图。这个类将包含一个 shapes 属性,用于存储绘图中的形状。

使用 DIP,您可以将 Shape 类拆分为两个接口:IShapeIDrawableIShape 接口将定义形状的通用属性和方法。IDrawable 接口将定义如何绘制形状。

您还可以创建一个名为 Drawing 的类来表示绘图。这个类将包含一个 shapes 属性,用于存储绘图中的形状。但是,Drawing 类不会直接依赖 IShapeIDrawable 接口。相反,它将依赖一个抽象类 Shape,该类实现了 IShapeIDrawable 接口。

这样,您就可以使用任何实现 IShapeIDrawable 接口的具体类来绘制形状。您不必担心具体类的实现细节。

总结

DIP 是 SOLID 原则中的最后一个原则。它规定,高级模块不应该依赖具象的低级模块,它们都应该依赖抽象。抽象不应该依赖具体,具体应该依赖抽象。

DIP 有许多优点,包括灵活性、可维护性和可测试性。您可以通过定义抽象接口或类、实现抽象接口或类以及在高级模块中使用抽象接口或类来使用 DIP。