依赖注入的全部意义(至少按照我的理解)是Button
不需要知道SwitchableDevice
它正在切换的具体内容。
抽象接口可能如下所示:
struct SwitchableDevice {
virtual void switchOn() = 0;
virtual void switchOff() = 0;
};
按钮可以这样实现:
struct Button {
SwitchableDevice& dev;
bool state = false;
Button(SwitchableDevice& d) : dev(d) {}
void buttonPress(){
if (state) { dev.switchOff(); }
else { dev.switchOn(); }
state = !state;
}
};
对于按钮,就是这样!没有人需要告诉按钮 的具体实现是什么SwitchableDevice
,换句话说:Button
和的实现SwitchableDevice
是解耦的。
a 的可能实现Lamp
如下所示:
struct Lamp : SwitchableDevice {
void switchOn(){std::cout << "shine bright" << std::endl;}
void switchOff(){std::cout << "i am not afraid of the dark" << std::endl;}
};
可以这样使用:
int main(){
Lamp lamp;
Button button(lamp);
button.buttonPress();
button.buttonPress();
}
希望有帮助...
好处是现在我们可以单独更改 theButton
和 the的实现Lamp
,而无需更改另一部分的任何内容。例如 aButtonForManyDevices
可能看起来像这样:
struct ButtonForManyDevices {
std::vector<SwitchableDevice*> devs;
bool state = false;
Button(std::vector<SwitchableDevice*> d) : devs(d) {}
void buttonPress(){
if (state) for (auto d: devs) { d.switchOff(); }
else for (auto d: devs) { d.switchOn(); }
state = !state;
}
};
同样,您可以完全更改 的行为Lamp
(当然,在SwitchableDevice
不必更改按钮上的任何内容的范围内。ButtonForManyDevices
甚至可以使用相同的方法来切换 a Lamp
、 aVaccumCleaner
和 a MicroWaveOven
。