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 used
Computer computer2(&keyboard);
computer2.useDevice(); // 输出: keyboard being used
// 程序扩展:添加打印机设备
Printer printer;
Computer computer3(&printer);
computer3.useDevice(); // 输出: printer being used
return 0;
}
通过这样的扩展,在不修改现有代码的情况下,实现了对新设备的支持。这正是依赖倒置原则的优势所在:高层模块不依赖于具体的底层模块,而是依赖于抽象接口;抽象不依赖细节,细节应依赖抽象;,从而使得系统更加灵活,易于扩展和维护。