好莱坞原则、依赖倒置、控制反转、依赖注入
https://blog.csdn.net/a695929533/article/details/50655365
好莱坞原则、依赖倒置、控制反转、依赖注入
这四个概念看起来比较像的,其实,在思想上也有很大的共同点,但是也是可以区分的。
好莱坞原则(Hollywood Principle):别打电话给我们,有事我会打电话给你。
好莱坞原则是用在系统的高层组件与底层组件之间。高层组件不应该直接调用底层组件,而是从容器获取。
例子:假设qq在线聊天,有聊天框和表情选择框,那么,打开聊天框,然后打开表情框,选择表情——这个过程不应该在聊天框的代码里出现(或者说,聊天框不应该参与直接调用表情框),而是应该聊天框告诉qq容器:我要调用A,虽然我不知道那是什么,然后容器提供A(表情框组件)。好处是,假如之后腾讯更新了更好的表情框,然后由容器控制生命周期,而聊天框则不参与。
依赖倒置原则(Dependency Inversion Principle):A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
依赖倒置原则更像是一种你应该养成的编程习惯,它要求你面对接口编程。
例子:类A,类B,类C,都有相同的属性,相同的方法,然后都有可能被类H调用(高层调用低层),这样H类的实例如果调用这三个类,那么这个类H就和这三个类就发生了耦合,但是如果把这三个类抽取出一个接口I,类H调用I(面向接口编程),H就依赖于接口,A、B、C也依赖于接口。好处是,在这种情况下,类与类之间的耦合降低了,不依赖具体类而是依赖于接口。
控制反转(Inversion of Control):控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。
依赖注入:对象(组件)的实例化依赖第三方实现。
例子:假如IA是接口,类A继承IA,类B里面有下面一行代码。
IA a = new A();
这时,类B是不是依赖于类A?
为了避免这种情况,我们可以这样,把=new A()这个实例化的代码,写在XML文档里,当需要实例化对象的时候,第三方从 XML里面读取,产生对象实例。这样做,解耦,方便我们修改,而且可以在程序编译之后,依然可以更替对象。
依赖查找:容器提供回调接口和上下文环境给组件。
依赖查找的概念是今天看到一个博文提到的,之前没有见过,据说EJB用的多,不过相对于依赖注入,它是比较落后的,不用过多关注,所以我们现在说控制反转,很多时候都是指的依赖注入。
抽象类和接口的区别:
在父类(接口)无属性,方法内没有代码的情况下,抽象类和接口是可以看成一样的。
但是一旦是这种情况,我们往往采用接口而非抽象类,为什么呢,因为抽象类不仅仅能做到接口内部的声明,还能声明属性,实现具体方法,杀鸡焉用牛刀?
但是抽象类的概念不能完全替代接口的概念,因为接口是多继承的,抽象类不可以,具体类可以继承多个接口,但只能继承一个类。
依赖于接口和依赖于抽象类的区别:
上面提到了抽象类和接口的区别,那么依赖于接口和依赖于抽象有什么区别呢?或者说,什么时候依赖于接口,什么时候依赖于抽象类?
其实再进一步问,那就是:什么时候用接口,什么时候用抽象类。
其实道理很简单,当你要处理的,是一个对象的时候就用抽象类,尤其是当所有的子类的某个方法的过程一样,完全可以用抽象类写final。而接口更像是一套标准。之所以有这样的区分,不就是为了开发人员轻松点么,编程这东西没有死的,怎么轻松怎么来。
网上有人通过对比好莱坞原则,认为控制反转和依赖倒置是粗鄙的、粗糙的,这种观念我们可以去看看,去理解,毕竟真金不怕火炼,如果真说得对,我们更应该高兴才是。
但我想说的是:世间安得双全法,不负如来不负卿。世界上没有绝对完美的语言,没有绝对好的设计模式,没有绝对高效的算法,也没有绝对正确的设计理念。因为脱离了业务和需求去谈语言、技术、框架等等都是不对的。一旦具体的业务和需求摆在面前,凭自己对各种原则,模式,语言的理解去选择,合适的才是最好的。