探索依赖倒置原则(DIP):将抽象与具体分开
2024-02-15 02:29:59
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:
- 首先,您需要定义一个抽象接口或类。这个接口或类应该定义您需要的高级模块的行为或功能。
- 接下来,您需要实现抽象接口或类。这些具体类应该实现抽象接口或类定义的行为或功能。
- 最后,您需要在高级模块中使用抽象接口或类。这样,您就可以使用具体类而无需担心具体类的实现细节。
DIP 的示例
为了更好地理解 DIP,让我们来看一个示例。假设您有一个绘图应用程序。这个应用程序允许用户绘制各种形状,如线条、矩形和圆形。
在没有使用 DIP 的情况下,您可能会创建一个名为 Shape
的类来表示形状。这个类将包含所有形状的通用属性和方法。您还可能会创建一个名为 Drawing
的类来表示绘图。这个类将包含一个 shapes
属性,用于存储绘图中的形状。
使用 DIP,您可以将 Shape
类拆分为两个接口:IShape
和 IDrawable
。IShape
接口将定义形状的通用属性和方法。IDrawable
接口将定义如何绘制形状。
您还可以创建一个名为 Drawing
的类来表示绘图。这个类将包含一个 shapes
属性,用于存储绘图中的形状。但是,Drawing
类不会直接依赖 IShape
或 IDrawable
接口。相反,它将依赖一个抽象类 Shape
,该类实现了 IShape
和 IDrawable
接口。
这样,您就可以使用任何实现 IShape
和 IDrawable
接口的具体类来绘制形状。您不必担心具体类的实现细节。
总结
DIP 是 SOLID 原则中的最后一个原则。它规定,高级模块不应该依赖具象的低级模块,它们都应该依赖抽象。抽象不应该依赖具体,具体应该依赖抽象。
DIP 有许多优点,包括灵活性、可维护性和可测试性。您可以通过定义抽象接口或类、实现抽象接口或类以及在高级模块中使用抽象接口或类来使用 DIP。