依赖倒转原则最经典的一句话就是:
高层不依赖于底层,依赖于抽象,抽象不依赖于细节,细节依赖于抽象。
画张图来说明一下:
以往都是高层与底层直接耦合,如果高层需要修改,可能底层要全部修改,若底层需要修改,高层也同样需要修改。这样对于长篇大论的代码是非常不利的,如果一个项目写成这样,估计也是没救了,牵一发就得动全身。
那么现在的结构一般是这样的:
高层和底层都依赖于一个抽象层,只要抽象层不变,底层要修改就只需要修改底层,高层若要修改,则只需要修改高层即可,目前不管什么的开发都是依照这个原理的。
给个实例:
class IReader {
public:
virtual string getcontents() = 0;
};
class Book : public IReader {
virtual string getcontents() {
return "从前有座山,山里有座庙,庙里有个老和尚,老和尚在讲故事 : 从前有座山";
}
};
class NewsPaper : public IReader {
virtual string getcontents() {
return "某某市一辆拉粪车不幸爆炸,附近一老大爷嘴长了半天都没合上,不知是吃惊了,还是吃翔了";
}
};
class Mother {
public:
void tell_story(IReader* ir) {
cout << ir->getcontents() << endl;
}
};
int main() {
Mother m;
m.tell_story(new Book);
m.tell_story(new NewsPaper);
system("pause");
return 0;
}
运行结果:
这个小程序的结构图就是这样的:
Mother代表高层,Book和NewsPaper代表底层,IReader就是高低层都依赖的抽象层。
若是增加、删除、或者修改底层,高层都不用变动,这样对代码的维护就瞬间上升了一个等级。
最后再补充一个电脑组装的例子,其思想是一样的:
#include<iostream>
using namespace std;
class Cpu {
public:
virtual void run() = 0;
};
class Mem {
public:
virtual void run() = 0;
};
class Disk {
public:
virtual void run() = 0;
};
class InterCpu : public Cpu {
virtual void run() {
cout << "I am InterCpu" << endl;
}
};
class JinShiTonMem : public Mem {
virtual void run() {
cout << "I am JinShiTonMem" << endl;
}
};
class WdDisk : public Disk {
virtual void run() {
cout << "I am WdDisk" << endl;
}
};
class Computer {
public:
Computer(Cpu *pc, Mem *pm, Disk *pd) :_pc(pc), _pm(pm), _pd(pd) {}
void work() {
_pc->run();
_pm->run();
_pd->run();
}
private:
Cpu *_pc;
Mem *_pm;
Disk *_pd;
};
int main() {
Computer com(new InterCpu, new JinShiTonMem, new WdDisk);
com.work();
system("pause");
return 0;
}
依赖倒置原则说白了就是通过抽象类来实现的。