前言
对于大部分小菜来说,当听到大牛们高谈DIP、IoC、DI以及IoC容器等名词时,有没有瞬间石化的感觉?其实,这些“高大上”的名词,理解起来也并不是那么的难,关键在于入门。只要我们入门了,然后循序渐进,假以时日,自然水到渠成。
好吧,我们先初略了解一下这些概念。
依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)。
控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。
依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。
IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。
哦!也许你正为这些陌生的概念而伤透脑筋。不过没关系,接下来我将为你一一道破这其中的玄机。
依赖倒置原则(DIP)
在讲概念之前,我们先看生活中的一个例子。
图1 ATM与银行卡
相信大部分取过钱的朋友都深有感触,只要有一张卡,随便到哪一家银行的ATM都能取钱。在这个场景中,ATM相当于高层模块,而银行卡相当于低层模块。ATM定义了一个插口(接口),供所有的银行卡插入使用。也就是说,ATM不依赖于具体的哪种银行卡。它只需定义好银行卡的规格参数(接口),所有实现了这种规格参数的银行卡都能在ATM上使用。现实生活如此,软件开发更是如此。依赖倒置原则,它转换了依赖,高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口。通俗的讲,就是高层模块定义接口,低层模块负责实现。
Bob Martins对DIP的定义:
高层模块不应依赖于低层模块,两者应该依赖于抽象。
抽象不不应该依赖于实现,实现应该依赖于抽象。
如果生活中的实例不足以说明依赖倒置原则的重要性,那下面我们将通过软件开发的场景来理解为什么要使用依赖倒置原则。
场景一 依赖无倒置(低层模块定义接口,高层模块负责实现)
从上图中,我们发现高层模块的类依赖于低层模块的接口。因此,低层模块需要考虑到所有的接口。如果有新的低层模块类出现时,高层模块需要修改代码,来实现新的低层模块的接口。这样,就破坏了开放封闭原则。