设计模式--依赖倒转原则
依赖倒转原则又称依赖倒置原则:
抽象不应该依赖细节,细节应该依赖于抽象。说白了,就是针对接口编程,不要针对实现编程。
依赖倒置原则包括三层含义:
1)高层模块不应该依赖低层模块,两者都应该依赖其抽象;
2)抽象不应该依赖细节;
3)细节应该依赖抽象。
看了上面的解释相信大家会和我一样会有一些疑问在脑海里,以下来具体说一说吧:
1)为什么要针对接口编程,而不是针对实现编程呢?
非常easy的一个样例。我们如今使用的电脑有各式的品牌。联想、神舟、戴尔等等,
电脑须要用到鼠标,键盘;如果鼠标、键盘是针对某一个品牌的机器实现去做的话,那么我们将会遇到什么问题呢?
那么我们市面上的键盘和鼠标就都是各式各样的,有一天鼠标。或键盘坏了。我们要怎么去买呢?难道记住这个电脑是什么品牌。什么型号,还有什么类型的去买么?这样会疯掉的。如今我们的电脑基本上都是使用USB接口的了,不管是键盘也好,鼠标也好,我们仅仅要买USB接口的就能够使用了,同一时候,使用USB接口还能够有其它的扩展。仅仅要实现了,这个接口,实现怎么样都没关系。比如,实现了USB接口的小台灯,仅仅要接上USB线就能够照明了;又如实现了USB
接口的充电器,接到我们的电脑上就能够充电了。
2)高层模块不应该依赖低层模块,两者都应该依赖其抽象又怎样理解呢?这个问题也能够这么问:为什么要叫倒置(倒转)呢?
在面向过程的开发中,为了使用经常使用的代码能够复用,一般都会把这些经常使用的代码写成许很多多函数的程序库,这样我们做新项目的时候,就去调用这些函数就能够了。
比如:我们做的项目大多要訪问数据库。所以我们就把数据库的代码写成了函数,每次做新项目时就去调用这些函数。这也就是高层依赖于低层模块了。
问题就出如今这里了,我们在做新项目的时候,会发现业务逻辑的高层模块是一样的,我们希望能重用这些高层模块。可是这些高层模块和低层模块的数据库绑定在一起了,这样我们就没办法复用这些高层模块了。
假设我们的高层模块和低层模块都依赖于抽象,详细一点就是依赖于接口或抽象类。仅仅要接口够稳定。那么不论什么一个的更改都不用操心其它受到影响了。
3)为什么依赖了抽象的接口或是抽象类。就不怕更改了呢?要解决问题,先看看里氏替换原则。
里氏替换原则:
一个软件实体假设使用的是一个父类的话,那么一定适用于其子类,并且它察觉不出父类对象和子类对象的差别。
也就是说。在软件里面。把父类都替换成它的子类。程序的行为没有变化;
简单的说:子类型必须可以替换掉它们的父类型。比如:企鹅在生物学分类上是属于鸟的,可是在编程中,企鹅就不能以父类的(鸟)的身份出现。
如果有一个鸟的父类,拥有一个会飞的方法fly(),我们是不能让企鹅继承于鸟的,这样当子类能够替换掉父类,软件单位的功能不受到影响时,父类才干真正的被复用,
而子类也可以在父类的基础上加入新的行为。
比如:猫是继承动物类的,以动物的身份拥有吃、喝、跑、叫等行为。
可当某一天。我们须要狗、牛、羊也拥有类似的行为。因为它们都是继承于动物,所以除了更改实例化的地方,程序其它地方就须要改变了。
正是因为子类型的可替换性才使得使用父类类型在的模块在无需改动的情况下就能够扩展。UML图:
高层模块依赖于接口或抽象类。低层模块实现接口或抽象类。依赖倒置原则事实上就是谁也不依靠谁。除了约定的接口,这样大家都能够灵活自由了。