在面向过程开发中,经常会有代码复用,一般就把常用代码写成许许多多函数的程序库,这样在做新项目时,去调用这些低层的函数就可以。调用这些函数就叫高层模块依赖低层模块,高层模块和低层模块就绑定在了一起。但是实际问题中,高层模块依赖低层模块会造成高层模块和低层模块复用性降低,所以为了解决这个问题,设计模式中提出一个依赖倒转原则。
依赖倒转原则(DependenceInversionPrinciple)
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。即针对接口编程,不要针对实现编程。
看这个定义的时候有些不懂什么高层模块,低层模块,或者抽象和细节。但是细细的分析:
依赖倒转其实就是谁也不要依靠谁,除了约定的接口,大家都可以灵活自如。依赖倒转可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。如果设计的各个部件或类相互依赖,这样就是耦合度高,难以维护和扩展,这也就体现不出面向对象的好处了。
依赖倒转原则,好比一个团队,有需求组,开发组,测试组,开发组和测试组都是面对同样的需求后,做自己相应的工作,而不应该是测试组按照开发组理解的需求去做测试用例,也就是说开发组和测试组都是直接面向需求组工作,大家的目的是一样的,保证产品按时上线,需求是不依赖于开发和测试的。
依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。不管是高层模块还是低层模块,都依赖于抽象(接口或抽象类),只要接口稳定,高低层变化,程序都不会受影响,并且复用性高。
总之,依赖倒置原则就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。
运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。设计接口的时候,只有多花些时间去思考和筹划,才能准确地实践这一原则。
举个简单的例子:公司里的领导(高层模块)不依赖员工(低层模块),大家都因为公司规定(抽象)有各自的事情做。规章制度(抽象类或接口)不会因为员工(细节)的变化而变化,但是不同的员工却要遵守制度。
在实际编程中,我们一般需要做到如下3点:
低层模块尽量都要有抽象类或接口,或者两者都有。
变量的声明类型尽量是抽象类或接口。
使用继承时遵循里氏替换原则。
这里提到了里氏代换原则,下一个文就来说说什么是里氏代换原则吧。