依赖倒置原则 (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();
    }
};

你可能感兴趣的:(设计模式,设计模式)