我见过许多用C++语言或者像Java这样的纯OO语言编写的程序,其中使用了类,但这些只是由程序组成的大型命名空间而已。
1 环依赖和依赖倒置
1.1 环依赖的例子
A类中包含B类的成员变量,B类也包含A类的成员变量,导致A和B相互依赖,称为“环依赖”。两个类不能分开,不能独立地使用。
#ifndef HUAN_YI_LAI#define HUAN_YI_LAIclass Customer;class Account{public:void setOwner(Customer* customer){owner = customer;}private:Customer* owner;};class Customer{public:void setAccount(Account* account){customerAccount = account;}private:Account* customerAccount;};#endif // !HUAN_YI_LAI
1.2 如何修改?
构建一个抽象的Owner接口基类,将Customer与Account的的关联关系变为如下所示:
#ifndef HUAN_YI_LAI#define HUAN_YI_LAI#include <string>class Owner{public:virtual ~Owner() = default;virtual std::string getName() const = 0;};class Account{public:void setOwner(Owner* customer){owner = customer;}private:Owner* owner;};class Customer : public Owner{public:void setAccount(Account* account){customerAccount = account;}virtual std::string getName() const override{// return something}private:Account* customerAccount;};#endif // !HUAN_YI_LAI
有了Owner的接口基类之后,我们在给Account设置Owner的时候就可以进行依赖注入,Account需要什么样的Owner,我们就可以通过setter注入什么Owner(可以是customer、User或其他子类)。最终我们通过依赖倒置和依赖注入将Customer和Accoutn进行了分离。
1.3 依赖倒置更直观的例子

Person类依赖了具体的工具,例如Person中有一个方法drive(Car),这样Person就对具体的交通工具产生了依赖,如果这个时候想要使用其它的交通工具如Bike,Bus,就需要修改Person类。
因此将原来的设计修改成了右边的样子,引入了抽象接口Transportation(交通工具),这样Person只需要依赖交通工具即可,至于到底选择何种工具,就交给IOC容器,进行依赖注入即可。
2 迪米特法则的例子
下面的例子中,Driver可以直接操作Car类,但是不能直接调用Engine、FuelPump等结构上更底层的类:

