C++ 中的依赖倒置原则(Dependency Inversion Principle,DIP)是SOLID设计原则中的一部分,它要求高层模块不应该依赖于低层模块,二者都应该依赖于抽象;而抽象不应该依赖于具体实现细节,具体实现细节应该依赖于抽象。这一原则可以通过使用抽象类和接口来实现。
通过一个简单的示例来说明依赖倒置原则的实现。假设有一个电脑类(Computer)需要连接各种外部设备,例如键盘(Keyboard)和鼠标(Mouse)。我们可以按照依赖倒置原则进行设计和实现。
// 抽象接口
class IDevice
{
public:virtual void use() = 0;
};// 鼠标类
class Mouse : public IDevice{
public:void use() override{cout << "mouse being used" << endl;}
};// 键盘类
class Keyboard : public IDevice
{
public:void use() override {cout << "keyboard being used" << endl;}
};// 电脑类
class Computer
{
private:IDevice* device;public:Computer(IDevice* dev) : device(dev) {}void useDevice() {device->use(); // 不依赖于具体的鼠标或键盘类型,而是依赖于抽象接口IDevice}
};
例子中,Computer 类不直接依赖于具体的鼠标或键盘类,而是依赖于抽象接口 IDevice。这样,无论将来增加了新的外部设备,只需要基于IDevice接口实现新的设备类,而无需修改Computer类的代码。
这种实现方式遵循了依赖倒置原则:高层模块(Computer)不依赖于底层模块(具体的鼠标或键盘类),而是都依赖于抽象(IDevice 接口)。这使得代码更加灵活,易于扩展和维护。
/
程序需要扩展或维护时,依赖倒置原则可以帮助我们以一种灵活的方式进行改进,而不会对现有的代码造成影响。
通过一个例子来说明:
给电脑类(Computer)增加一个新的外部设备,比如打印机(Printer),根据依赖倒置原则的设计,我们可以轻松地实现这一扩展。
首先,我们创建一个新的打印机类,实现 IDerice 接口:
// 打印机类
class Printer : public IDevice
{
public:void use() override {cout << "printer being used" << endl;}
};
然后,我们对 Computer 类进行扩展,将新的打印机设备传入:
int main()
{// 现有的设备Mouse mouse;Keyboard keyboard;// 创建电脑对象并使用现有的设备Computer computer1(&mouse);computer1.useDevice(); // 输出: mouse being usedComputer computer2(&keyboard);computer2.useDevice(); // 输出: keyboard being used// 程序扩展:添加打印机设备Printer printer;Computer computer3(&printer);computer3.useDevice(); // 输出: printer being usedreturn 0;
}
通过这样的扩展,在不修改现有代码的情况下,实现了对新设备的支持。这正是依赖倒置原则的优势所在:高层模块不依赖于具体的底层模块,而是依赖于抽象接口;抽象不依赖细节,细节应依赖抽象;,从而使得系统更加灵活,易于扩展和维护。