依赖倒置原则 Dependency Inversion Principle

依赖倒置原则 (Dependency Inversion Principle)

flyfish

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

A.高层模块不应该依赖于低层模块,他们都应该依赖于抽象。
B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

按照原则的做法设计一个类结构,该类的结构从高层模块开始到低层模块是这样的。
High Level Classes –> Abstraction Layer –> Low Level Classes

解释:
低层模块:举例 实现基本和主要操作的类(磁盘访问、网络协议等)
高层模块:封装复杂的逻辑(业务流等)

让我们来看一个经典的例子,一个拷贝模块,它从键盘上读取字符并将其写入打印机设备。
包含逻辑的高层模块类是copy类。低层模块类是KeyboardReader和PrinterWriter。

在糟糕的设计中,高层模块类直接使用,并且很大程度上依赖于低层模块类。在这种情况下,如果我们想要更改设计,将

输出一个新的FileWriter类中,那么我们必须在copy类中进行更改。
(让我们假设它是一个非常复杂的类,有很多逻辑,并且很难进行测试,类似log可以输出到屏幕,文件,远程计算上等)

为了避免这些问题,我们可以在高层模块类和低层模块类之间引入一个抽象层。由于高层模块包含复杂的逻辑,所以它们

不应该依赖于低层模块,所以新的抽象层不应该基于低层模块创建。低层模块基于抽象层创建。两边都依赖于抽象层。

// Dependency Inversion Principle - Bad example

class Worker 
{
public:
    void work() 
    {
        // ....working
    }
};



class Manager 
{
private:
    Worker worker;
public:
    void setWorker(Worker w) 
    {
        worker = w;
    }
     void manage() 
    {
        worker.work();
    }
};

class SuperWorker
{
public:
    void work()
    {
        //.... working much more
    }
};

好的例子
下面的代码支持依赖倒置原则。在这个新设计中,通过IWorker接口添加一个新的抽象层。现在,上述代码的问题得到了解决(考虑到高层逻辑中没有变化):

// Dependency Inversion Principle - Good example
class IWorker
{
public:
    void work() {}
};

class Worker :public IWorker
{
public:
    void work()
    {
        // ....working
    }
};

class SuperWorker :public IWorker
{
public: void work()
{
    //.... working much more
}
};

class Manager
{
private:
    IWorker worker;

public:
    void setWorker(IWorker w)
    {
        worker = w;
    }

    void manage()
    {
        worker.work();
    }
};

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...