您的位置:首页 > 其它

面向对象设计原则之依赖倒置原则(Dependency Inversion Principle)

2008-12-13 13:15 429 查看
最近在公司给BTS team做了一次软件设计原则中依赖倒置原则的presentation。下面谈谈我对该原则的理解。
就字面上理解,依赖倒置原则包含两个层次的含义。一是依赖,二是倒置。什么是依赖呢?我们知道,我们万事万物都处于对象世界中,事物之间相互联系着。在对象世界中没有孤立存在的事物。而这种联系就是我们所指的依赖。我们建立这种事物间的依赖关系就是依赖倒置原则所要讨论的问题。
在这里我们需要引入抽象的概念,在辩证唯物主义哲学中,指出普遍规律的提出必须经过抽象。由此可见抽象在物质世界中占据重要的地位。那什么是抽象呢?一句话:提取事物间共性的行为或者过程。在面向对象的设计中,设计是不是做得好,直接同你的抽象思维有着紧密的联系。
在依赖倒置原则中,他提倡的是模块应该依赖于抽象,不应该依赖于具体。而倒置则指的是依赖关系的建立是在抽象之间或者抽象与具体之间,同传统的依赖关系建立在具体之间是背道而驰的。
我们将该原则应用到我们设计中,会给我们带来什么好处呢?具体实现之间松耦合,模块仅仅依赖于接口,抽象。而把耦合转移到抽象之间或抽象和具体之间。
1. 便于单元测试。
2. 便于模块复用。
3. 便于模块移植。
4. 便于功能扩展。
该原则也体现在很多设计模式中,比如抽象工厂,观察者,桥以及命令模式。
但是该原则并没有完全消除耦合,只能说把耦合转移到另外一个地方。耦合是不可避免的,因此我们在设计中也要防止过设计,过分依赖于设计模式,设计原则。要立足于现有需求和开发者开发类似项目的经验。切忌无中生有。但是同时我们也要尽量避免在开发中不必要的重构,可能这点有点违背Agile的开发思想。总之一句话,我们不能走极端。
在开发设计中的一些Tips:
1. 类成员尽量指向基类指针:
class Base {};
class Derived: public Base {};
class A
{
private:
Derived * pDerived;
};
更好的做法:
class A
{
private:
Base * pDerived;
};

2. 尽可能避免过早与其他模块建立依赖:
class A
{
public:
void pirnt(){}
};

class B
{
public:
void test()
{
a.print();
}
private:
A a;
};

更好的做法:
class B
{
public:
void test(A a)
{
a.print();
}
};

3. 接口好过抽象类:
class A
{
public:
virtual int test() = 0;
void print(){}

private:
B b;
};

更推荐的做法:
class A
{
public:
virtual int test() = 0;
};

class B:public A
{
public:
void print(){}
int test(){}
private:
B b;
};

4. 尽量使用类前向申明,摆脱编译时的依赖。
// B.h
#include “A.h”
Class B
{
public:
int initialize();
private:
A * a;
};

更推荐的做法是:
//B.h
Class A;
Class B
{
public:
int initialize();
private:
A * a;
};
即便是B.h现在还没有,另外一个模块:
//C.cc
#include “B.h”
int test()
{
B b;
b.initialize();
}

可以通过编译,同时这样做可以避免重复include头文件引出的循环依赖问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐