Posted on 2016-07-10 15:59
小菜枫 阅读(411)
评论(0) 编辑 收藏 引用 所属分类:
学习笔记
依赖倒置原则:Dependence Inversion Principle,简称DIP。
定义:High level modules should not depend upon low level modules.Both should depend upon abstractions.
Abstractions should not depend upon details.
Details should depend upon abstractions。
翻译成中文如下:
- 高层模块不应该依赖低层模块,两者都应该依赖抽象
- 抽象不应该依赖细节
- 细节应该依赖抽象
由来:Draw类依赖于Pic类,如果要将Draw类更改为依赖于Text类,则必定要修改Draw类才能达成目的。这种情况下,Draw类就是属于上面所提到的高层模块,Pic类和Text类是底层模块。
方案:将Draw类更改为依赖于接口I,Pic类和Text类各自实现接口I,Draw类通过接口I与Pic类/Text类发生关联。
例子:
原始版本:DrawManager类管理画图。
class Pic
{
public:
Pic(void){};
~Pic(void){};
void Draw()
{
cout<<"Pic ";
}
};
class DrawManager
{
public:
DrawManager(void){};
~DrawManager(void){};
void Draw(Pic* objname)
{
objname->Draw();
cout<<"is drawing.."<<endl;
};
};
需求变更一版本:界面需要对文字进行绘制。
需求变更一版本之解决方案一:
class Pic
{
public:
Pic(void){};
~Pic(void){};
void Draw()
{
cout<<"Pic ";
}
};
class Text
{
public:
Text(void){};
~Text(void){};
void Draw()
{
cout<<"Text ";
}
};
class DrawManager
{
public:
DrawManager(void){};
~DrawManager(void){};
void Draw(Pic* objname)
{
objname->Draw();
cout<<"is drawing.."<<endl;
};
void Draw(Text* objname)
{
objname->Draw();
cout<<"is drawing.."<<endl;
}
};
需求变更一版本之解决方案二:
class Obj
{
public:
Obj(void){};
~Obj(void){};
virtual void Draw() = 0;
};
class Pic:public Obj
{
public:
Pic(void){};
~Pic(void){};
virtual void Draw()
{
cout<<"Pic ";
}
};
class Text:public Obj
{
public:
Text(void){};
~Text(void){};
virtual void Draw()
{
cout<<"Text ";
}
};
class DrawManager
{
public:
DrawManager(void){};
~DrawManager(void){};
void Draw(Obj* objname)
{
objname->Draw();
cout<<"is drawing.."<<endl;
};
};
需求变更一版本之解决方案三:
#define interface struct
interface Obj
{
public:
virtual void Draw()=0;
};
class Pic:public Obj
{
public:
Pic(void){};
~Pic(void){};
virtual void Draw()
{
cout<<"Pic ";
}
};
class Text:public Obj
{
public:
Text(void){};
~Text(void){};
virtual void Draw()
{
cout<<"Text ";
}
};
class DrawManager
{
public:
DrawManager(void){};
~DrawManager(void){};
void Draw(Obj* objname)
{
objname->Draw();
cout<<"is drawing.."<<endl;
};
};
总结
由上面的需求变更的三种实现方案,其中各自优缺如下:
方案一:不遵循依赖倒置原则
好处:新增加一个组件,客户端对应增加一个方法,简单明了
坏处:需要更改到DrawManager类
后续增加新组件,DrawManager类每次都需要更改
方案二:遵循依赖倒置原则:基于抽象类
好处:后续新增组件不影响DrawManager类原有逻辑
组件的实现变更不影响DrawManager类
低耦合
坏处:增加一个text,缺增加了两个类(obj,text)
方案三:如方案二(特别说明:c++实际没有interface,这里只是使用struct模拟interface使用)