依赖倒置是基于多态实现的,指的是高层模块不应该依赖底层模块,二者都应该依赖于其抽象,抽象不应该依赖于细节,细节应该依赖抽象。
假设类A直接依赖于类B,如果要将类A修改成依赖类C,则必须通过修改类A的代码来达成.一般类A是高层模块,内部组成较为麻烦,
如果修改类A,会带来麻烦和风险
第一幅图中,如果高层模块发生了变动,中间和底层模块都要发生变动,若底层发生变动,高层也会受到相应的影响
第二幅图中增加了中间抽象层,如果底层发生改动,高层则不受影响,高层的改动同样不会影响底层,极大地降低了耦合性
我们可以通过这么一个例子来说明:
class Mother {
public:
void tellStory(Book* book) {
cout << reader->getContents() << endl; //mother依赖于book
}
};
class Newspaper {
public:
string getContents() {
return "News:";
}
};
class Book {
public:
string getContents() {
return "book's content";
}
如果mother类要在tellstory中传入newspaper类对象,则需要对mother类中的tellstory函数进行修改,这样增加了模块间耦合性
根据依赖倒置原则,我们可以增加一个接口来降低耦合性
class IReader { //创建一个接口
public:
virtual string getContents() = 0;
};
class Mother {
public:
void tellStory(IReader* reader) {
cout << reader->getContents() << endl; //mother依赖于book
}
};
class Book:public IReader {
public:
string getContents() override{
return "Book's content";
}
};
class Newspaper:public IReader {
public:
string getContents() override{
return "News:";
}
};
这样一来,无论怎样扩展content都无需对mother类进行修改了,只需通过接口类的指针调用相关模块就可以了
int main() {
Newspaper n;
Book b;
IReader* pr;
Mother m;
pr = &n; //假如要newspaper
m.tellStory(pr);
pr = &b; //假如要book
m.tellStory(pr);
}