核心本质
- 你可能会说 其核心本质 是类似万物皆为对象 的一种设计思想,又或者说是 封装继承多态的运用,又或者是其他的什么. 我觉得,这些说法也对,不过今天要说的是另一个概念: 依赖反转.
- 用了个标题党的标题,答案就开门见山一些。 其核心本质,乃是通过安全便且捷的多态实现的 依赖反转;及 由此带来的依赖关系的灵活性,以及 系统架构的灵活性。
什么是依赖反转
用一张图说明下,如下:
图中,class1 要调用 class2 的函数, 依赖反转 是通过接口实现多态,进而实现依赖反转。
如果interf2没有这个接口,即图中 蓝色线条的情况。那么classe1 直接调用 class2,那么依赖方向 和控制流方向 是一致 的,都是由 class1 到 class2.
如果有 interface2 这个接口, class2 实现了 interface2, class1调用interface2; 此时的依赖方向 就是 变成了 class2,依赖 interface2. 而这个 依赖方向和控制流的方向是相反的, 这个相反就叫做依赖反转
为什么不是 封装 继承 多态
至于为什么面向对象的核心特质 不是面向对象的三大特质,原因也很简单,
在面向对象语言出现之前,封装、继承、多态这样概念和 做法已经出现了。甚至有些地方比面向对象语言的设计更为严格。关于封装,如果用C语言去实现封装,其封装性反而比面向对象语言(Java\C++ 等)更好. 用C 语言include 一个文件去使用,只能使用其内的函数和数据类型,数据类型的细节和函数的实现则完全不可见;而现在常见的面向对象语言,一个类引用对象的时候反而能看到要使用的数据结构的细节,甚至还要随着它的变化而改变自身.
关于继承,利用组合同样能达到类似继承的效果,而且大多数时候 组合有着比继承更高的灵活性。所以,在使用面向对象的编程语言时,我建议你在用继承的时候考虑下,是不是组合更为合适。 不过面向对象语言确实在数据结构的封装上提供了很大的便利性!
关于多态,面向对象出现之前,多态也已经存在了. 最典型的多态例子就是 Linux 操作系统的IO设备,都是插件形式的. 有一个说法叫 "程序与设备无关"; 即面向不同的IO设备,程序应该是感知不到的, 不管当前程序要写入的是标准输入,或者文件,或者其他的什么. 其好处 是不言而喻的. 那么面向对象语言出现之前,多态的使用其实不那么的多,为什么呢? 因为其实现是函数指针的形式, 复杂又危险! 面向对象语言使得 多态的实现变得简易且安全.
面向对象让 多态 变得容易和安全
首先,多态实现的原理到底是什么?多态,其实就是指针的一种特殊应用 。
为什么这么说呢,常见的多态就是把把接口当成一个对外的入口,程序从这个入口处取出一组数据,或者一个函数去使用。 其实这就是一个指针,让这个指针指向不同的位置去拿不同的东西来使用。
面相对象语言出现之前,用C等高级语言去实现这个还是比较麻烦且所以出错的,这个问题导致多态无法普遍运用。而用新的面向对象语言去实现多态,就是一件很简单的事情了。
依赖反转的妙处--架构的灵活性
说了这么多,终于说到最后,最重要的东西了。
面向对象语言,让多态的实现变得简单安全的意义是什么?意义就是通过多态实现的依赖反转也变得简单安全,这给程序架构设计带来了很大的灵活性。
如果没有依赖反转,那么架构的选择就比较单一,按照控制流的方向从上到下;如果此时 底层被依赖较多的组件 频繁的变动,那么上层的组件也必须要跟着变动,这将会十分的痛苦!
如果有依赖反转了这个东西,我们就可以自如的控制依赖的方向,让变化少的组件被依赖,让变化多组件到顶层依赖别的组件。这样,经常变化的组件 就不必引起其他的组件跟着变化进而增加工作量了.
比如这个组件,依赖方向原本是, 用户界面依赖业务逻辑,依赖数据库;我们可以用接口让依赖方向从用户界面到 业务逻辑. 这样, 不那么易变的用户界面,就到了 更容易变化的业务逻辑的下方. 程序结构更加的合理.
以上,欢迎补充和指正.
有收获记得点赞哦~~
关注我互关