在面向对象编程的过程中,多态作为其中一个重要特性,具有强大的作用。
从架构设计的角度,使用多态可以实现依赖反转。
依赖反转指的是:
通过使用接口的方式,将模块与模块之间的依赖关系,由【调用者】依赖于【被调用者】,转变为【被调用者】依赖于【调用者】(或称为【被调用者】继承自【调用者】),以此来实现【调用者】不受【被调用者】修改的影响的目的。
下面使用伪代码来说明:
当不使用依赖反转时,程序设计如下:
调用的类:UserClass,需要被调用的类SubClassA和SubClassB,主程序main
/* SubClassA.h */
class SubClassA
{
public:
void Print(){
cout<<"SubClassA Print is called"<<endl;
}
}
/* SubClassB.h */
class SubClassB
{
public:
void Print(){
cout<<"SubClassB Print is called"<<endl;
}
}
/* UserClass.h */
#include "SubClassA .h"
#include "SubClassB .h"
class UserClass
{
public:
void Print(){
SubClassA *a = new SubClassA ;
a->Print();
SubClassB *b = new SubClassB ;
b->Print();
}
}
/* main.cpp */
#include "UserClass.h"
void main(){
UserClass* user = new UserClass
user->Print();
}
在这样的设计下,类UserClass依赖SubClassA和SubClassB,这意味着:
1、SubClassA或SubClassB的修改将影响到UserClass,需要重新编译和部署。
2、当需要扩展与SubClassA和SubClassB类似的SubClassC、SubClassD……时,UserClass也需要做相应的改动,增加对新类型的支持代码。
当使用了依赖反转时,程序设计如下:
接口类:IBaseClass
子类:SubClassA和SubClassB
需要调用子类的类:UserClass
主程序main
/* IBaseClass.h */
class IBaseClass
{
public:
virtual void Print() = 0
}
/* SubClassA.h */
#include "IBaseClass.h"
class SubClassA : public IBaseClass
{
public:
void Print(){
cout<<"SubClassA Print is called"<<endl;
}
}
/* SubClassB.h */
#include "IBaseClass.h"
class SubClassB : public IBaseClass
{
public:
void Print(){
cout<<"SubClassB Print is called"<<endl;
}
}
/* UserClass.h */
#include "IBaseClass.h"
class UserClass
{
public:
UserClass(IBaseClass* ptr){
m_ptr = ptr;
}
void CallPrint(){
m_ptr->Print();
}
private:
IBaseClass* m_ptr;
}
/* main.cpp */
#include "SubClassA.h"
#include "SubClassB.h"
#include "UserClass.h"
void main(){
SubClassA* a = new SubClassA;
SubClassB* b = new SubClassB;
UserClass user_a(a);
UserClass user_b(b);
user_a.CallPrint();
user_b.CallPrint();
}
可能看起来,绕了一大圈,还是在main中引入了SubClassA.h和SubClassB.h,但其实关键点就在于此。通过接口的设计方式,UserClass摆脱了对类SubClassA和类SubClassB的依赖,好处在于:
1、类SubClassA和类SubClassB的修改,不会使UserClass需要重新编译;
2、当需要扩展与SubClassA和SubClassB类似的SubClassC、SubClassD……时,根本不需要对UserClass有任何改动,只要新增的类仍然继承自IBaseClass即可。
以上是博主在自学过程中的一点心得体会分享,由于博主的技术水平有限,有不正确的地方,还望各位大佬在评论区指出,欢迎交流指点。
参考文档:
https://blog.csdn.net/niu2212035673/article/details/77823666